spring beans 自动注入的概念

来源:互联网 发布:新浪微博数据抓取 编辑:程序博客网 时间:2024/06/07 05:09

在spring框架中,学习在配置文件中设置bean的依赖是很好的实践,但是spring容器也可以利用bean间的关系实现自动注入,这意味着可以让spring自动通过检测Beanfactory来决定为你的bean输入其他的bean。自动装配可以指定一些类bean并且启用他们,而另一些beans不会被自动装配。

自动装配的模式:

1、NO:一点也没有自动装配,bean的引用关系引用元素定义

2、byName:通过属性的名字自动装配,这种方式将会查找需要被注入的bean的准确的名字

3、byType:允许在容器中类型完全一致的属性注入,如果没有的话,将会报出致命异常

4、constructor:这种方式和byType类似,但是使用于有构造参数的情况

5、autudetect:通过检测bean来决定选择constructor还是使用byType

自动注入功能有5种,分别是NO、byName、byType、constructor和autudetect,默认情况下是NO这种情况,也就是自动装配时关闭的。

在配置文件中不同的注入方式

像在上边列出的一样,有5中自动注入的方式,我们来一个一个讨论。
no:这个选项对于spring框架是默认的,意味着自动装配是关闭的,你必须要明确的在bean的定义时设置依赖关系
byName:这个是使用bean的名字进行依赖注入,当在bean中注入一个属性的时候,利用属性的名字在配置文件中查找匹配的bean,如果找到了这样的bean,就会注入到属性中去,如果没有就会报错。
【byName注入的例子】
byType:这种依赖注入根据bean的类型,当在bean中注入一个属性的时候,属性的类的类型被用来查找在配置文件中匹配的bean,如果找到了,就会注入到属性中去,如果没有找到就会报错
【byType注入的例子】
constructor:通过构造函数注入和通过类型注入很相似,但是适用于构造函数的参数。在激活的自动注入的bean中,它将会寻找构造函数参数的类的类型,然后根据属性的类型做自动注入,请注意如果在容器中没有构造函数参数对应的类型,那么将会报错。
【constructor注入的例子】
atuodetect:自动检测注入要么使用constructor注入要么使用byType注入,首先它将会寻找构造函数有效的参数,如果找到的话那么就使用constructor这种方式,如果这种有参数的构造方法在bean中没有定义,byType这种方式就会被选择。
【atuodetect注入的例子】

使用@Autowired注解自动注入

除了使用在配置文件中使用自动注入,还可以在bean的类中使用@Autowired注解。为了在类中使用这种注解的方式,你必须在spring application中开启注解的方式:
<context:annotation-config />

或者在配置文件中使用AutowiredAnnotationBeanPostProcessor的定义

<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

现在注解的配置已经启用,可以在类中使用@Autowired注解了,有三种方式
(1)@Autowired加在属性上边
当在属性上使用@Autowired的时候,和在配置文件中使用byType是一样的
public class EmployeeBean{    @Autowired    private DepartmentBean departmentBean;     public DepartmentBean getDepartmentBean() {        return departmentBean;    }    public void setDepartmentBean(DepartmentBean departmentBean) {        this.departmentBean = departmentBean;    }    //More code}

(2)在setters方法上使用@Autowired
当在setter方法上使用@Autowired的时候,和在配置文件中使用byType是一样的
public class EmployeeBean{    private DepartmentBean departmentBean;     public DepartmentBean getDepartmentBean() {        return departmentBean;    }     @Autowired    public void setDepartmentBean(DepartmentBean departmentBean) {        this.departmentBean = departmentBean;    }    //More code}

(3)在constructor上使用@Autowired
当在bean的构造方法上使用@Autowired的时候,它和在配置文件中使用constructor是一样的
package com.howtodoinjava.autowire.constructor; public class EmployeeBean{    @Autowired    public EmployeeBean(DepartmentBean departmentBean)    {        this.departmentBean = departmentBean;    }     private DepartmentBean departmentBean;     public DepartmentBean getDepartmentBean() {        return departmentBean;    }    public void setDepartmentBean(DepartmentBean departmentBean) {        this.departmentBean = departmentBean;    }    //More code}

使用@Qualifier处理冲突

像我们刚刚看到的一样,如果我们使用byType注入这种方式来查找属性的依赖,如果没有找到这种类型,那么就是抛出异常,但是如果一个类型的多个bean找到了呢
在这种情况下,spring不会选择正确的bean进行注入,你得通过使用qualifiers来帮助容器
为了决定使用哪个bean要使用qualifiers,我们需要使用和@Autowired注解一起@Qualifier注解,并且将bean的名字作为注解的参数,看看下边的例子:
public class EmployeeBean{    @Autowired    @Qualifier("finance")    private DepartmentBean departmentBean;     public DepartmentBean getDepartmentBean() {        return departmentBean;    }    public void setDepartmentBean(DepartmentBean departmentBean) {        this.departmentBean = departmentBean;    }    //More code}

重复的bean如下:
<?xml version="1.0" encoding="UTF-8"?><beans>    <context:annotation-config />     <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">        <property name="fullName" value="Lokesh Gupta"/>    </bean>    <!--First bean of type DepartmentBean-->    <bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >        <property name="name" value="Human Resource" />    </bean>     <!--Second bean of type DepartmentBean-->     <bean id="finance"      class="com.howtodoinjava.autowire.constructor.DepartmentBean" >        <property name="name" value="Finance" />    </bean></beans>

通过使用required=false让自动注入的错误安全

即使你再使用自动注入依赖的时候已经及其小心了,你也可能发现奇怪的错误,为了解决这个问题,你应该使自动装配变得可选,这样即使没有找到依赖应用程序也不会抛出异常,自动注入将会被忽视。
有两种方式:
(1)如果你指定的特定的bean,在@Autowired中使用required="false"
@Autowired (required=false)@Qualifier ("finance")private DepartmentBean departmentBean;

(2)如果你在所有的注入上都想变得可选,那么使用下边的这种方式:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">    <property name="requiredParameterValue" value="false" /></bean>


将一个bean从自动装配中排除

默认情况下,自动装配扫描和匹配所有的bean,如果你不想通过自动装配模式将bean注入,你可以使用autowire-candidate设置为false
(1)使用autowire-candidate置为false,可以使一个bean从自动装配的候选中排除。
<?xml version="1.0" encoding="UTF-8"?><beans>    <context:annotation-config />     <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">        <property name="fullName" value="Lokesh Gupta"/>    </bean>    <!--Will be available for autowiring-->    <bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >        <property name="name" value="Human Resource" />    </bean>     <!--Will not participate in autowiring-->     <bean id="finance"      class="com.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false">        <property name="name" value="Finance" />    </bean></beans>

(2)另一个选择是通过模式匹配来限制自动装配的bean。最高层的元素在default-autowire-candidates属性中接收一个或者多个模式,例如限制任何bean装配的状态,通过匹配Impl,提供一个*Impl。
<?xml version="1.0" encoding="UTF-8"?><beans default-autowire-candidates="*Impl,*Dao">    <context:annotation-config />     <bean id="employee" class="com.howtodoinjava.autowire.constructor.EmployeeBean" autowire="constructor">        <property name="fullName" value="Lokesh Gupta"/>    </bean>    <!--Will be available for autowiring-->    <bean id="humanResource" class="com.howtodoinjava.autowire.constructor.DepartmentBean" >        <property name="name" value="Human Resource" />    </bean>     <!--Will not participate in autowiring-->     <bean id="finance"      class="com.howtodoinjava.autowire.constructor.DepartmentBean" autowire-candidate="false">        <property name="name" value="Finance" />    </bean></beans>

注意:bean定义的autowire-candidate属性的准确值''true'或者"false",有很高的优先级,对于这种bean,模式匹配不会生效。
以上这些就是spring框架中自动装配的所有特征。
原文链接:http://howtodoinjava.com/2013/05/08/spring-beans-autowiring-concepts/
0 0