首页 > 学院 > 开发设计 > 正文

基于注解自动装配Bean

2019-11-06 06:16:44
字体:
来源:转载
供稿:网友

      自动装配(autowiring):有助于减少<PRoperty>和<constructor-arg>,让spring自动识别如何装配Bean的依赖关系。

      自动检测(autodiscovery):让spring自动识别那个类要被装配成spring Bean,减少对<bean>元素的使用。

1.自动装配Bean属性

     

1.1    4中类型的自动装配

      1.byName:把与Bean的属性具有相同名字(或者ID)的其他Bean自动装配到Bean的对应属性中。如果没有与属性的名字相匹配的Bean,则该属性不进行装配。

      2.byType:把与Bean的属性具有相同类型的其他Bean自动装配到Bean的对应属性中。如果没有与属性的类型相匹配的Bean,则该属性不进行装配。

      3.constructor:把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean构造器的对应入参中。

      4.autodetect:先按constructor来装配,失败了按byType来装配。

1.1.1  byName自动装配

 

<bean id="aaa" clas=""/><bean id="bbb" class="" >   <property name="aaa" ref="aaa"/></bean>

如果bbb中aaa属性名字和Bean的id相同,则可以自动装配。如果bean的id和property的name相同,那么可以变为下面的这种方式:

<bean id="aaa" clas=""/><bean id="bbb" class="" autowire="byName"> </bean>

如果一个Bean中属性和其他Bean的id相同就会自动装配,可是自己不需要自动装配。byName的缺点就是要假设属性名和Bean的id要一样。

1.1.2  byType自动装配

      跟byName一样,只是ByType不去找属性名一样,而是去找属性的类型。

<bean id="aaa" clas="A"/><bean id="bbb" class="" >   <property name="aaa" ref="aaa"/></bean>如果bbb中属性aaa为A类型,则可以byType自动装配,把autowire="byType"

<bean id="aaa" clas="A"/><bean id="bbb" class="" autowire="ByType">   </bean>      如果byType找到多个Bean,那么抛出异常,应用只允许存在一个Bean与需要的自动装配的属性相匹配。byName不会找到多个,因为Bean的id是不一样的。解决的办法就是可以标识一个首选Bean,也可以让其他Bean失去资格。<bean>元素有个primary属性表示首选Bean,但是默认为true,所有的Bean都是首选Bean,所以要把非首选的Bean设置为false。<bean>的

autowire-candidate属性可以设置为false表示自动装备忽略Bean的资格。

1.1.3 constructor自动装配

      不需要<constructor-arg>元素,autowire为constructor。和byType有相同的局限性,也是按照类型去匹配的,一个构造器参数对应多个Bean,还有一个Bean对应多个构造器。

      

1.2 默认自动装配

      如果所有的bean都按照同一类型自动装配,可以再<beans>元素中加default-autowire属性。这个属性默认为none,表示不使用自动装配。可以设置为byName等类型。<bean>中的autowire会覆盖default-autowire属性。<property>会覆盖自动装配的值。

      autowire=“constructor”时,不能与<constructor-arg>同时存在。其他类型可以于<property>同时存在。

      

2.  使用注解装配

      spring容器是默认禁用注解装配的。要启动,最简单的就是context命名空间的<context:annotation-config/>

      1.spring自带的@Autowired注解

      2.JSR-330的@Inject注解

      3.JSR-250的@Resource注解

2.1 @Autowired

      有了这个注解,spring会按byType自动装配。这个注解可以加在setter方法上,还可以加在需要自动装配Bean的任意方法上,还可以加在构造器上。这个注解可以直接加在属性上,并删除setter方法。

       这个注解必须只能有一个Bean匹配到注解的参数或属性中。没有匹配Bean或匹配多个Bean会有问题。

2.1.1可选的自动装配

       默认情况下,这个注解标识的属性或参数必须是可装配的。没有Bean装配到,就会报NoSuchBeanDefinitionException。这个时候可以设置required=false来设置自动装配是可选的。没有匹配到Bean就会为null。

@Autowired(required=false)private A a;       required可以用于@Autowired使用的任何地方,但是在构造器中,只能有一个构造器是required为true,其他都要设置为false。当@Autowired标注多个构造器时,spring会从满足条件的构造器中选择入参最多的构造器。

2.1.2限定歧义性的依赖        有可能spring找到了多个满足条件的Bean,可以使用@Qualifier注解。

@Autowired@Qualifier("a")//指定a,默认从id找private A a;        相当于把byType转为了byName。缩小了自动装配Bean的范围。还可以在Bean中声明

<bean class="A">      <qualifier value="a"/>//可以限定这个Bean为a</bean>@Qualifier("a")//可以限定这个Bean为aclass A implement B{}        @Autowired是减少spring xml配置的一种方式。但是使用它的类会引入spring的特定依赖。

2.2 @Inject       

@Injectprivate A a;       这个注解和@Autowired一样可以自动装配,可以装配属性,方法,构造器。但是没有required属性所以装配的Bean必须存在,不存在会报错。

       2.2.1限定@Inject所标注的属性

       @Autowired的@Qualifier与@Inject的@Named对应

@Inject@Named("a")private A a;      @Qualifier注解缩小Bean的选择范围(默认使用Bean的id),@Named通过Bean的Id标识可选择的Bean。

2.3在注解注入中使用表达式

        @Value可以装配简单值。

@Value("jack")//这里面是一个表达式private String name;
@Value("#{abc.name}")private String name;

3.自动检测Bean

       <context:component-scan>除了完成<context:annotation-config>一样的工作外,还允许Spring自动检测Bean和定义Bean。

<context:component-scan//替代了<context:annotation-config>base-package="包">//会扫描指定的包及其子包,并找出能够自动注册的spring Bean     </context:component-scan>        

3.1为自动检测标注Bean

      默认情况下<context:component-scan>查找使用构造型注解所标注的类。

      1.@Component:通用的构造型注解,表示该类为spring组件

      2.@Controller:表示该类定义为spring mvc controller

      3.@Repository:表示该类为数据仓库。

      4.@Service:表示该类定义为服务

      5.使用@Component标识的任意自定义注解         

3.2过滤组件扫描

       <context:component-scan>下面还有子元素<context:include-filter>和<context:exclude-filter>。只是用<context:component-scan>的情况下,spring只会去找基于注解的组件。但是还要包含一个没有注解的接口的所有实现类要怎么办。就是用<context:include-filter>

<context:component-scanbase-package="包">     <context:include-filter type="assignable" expression="xxx.abc"/></context:component-scan>type的5中类型

1.annotation:扫面指定注解所标注的类,通过expression指定注解。

2.assignable:扫面派生于expression指定类型的哪些类。

3.aspectj:扫面与expression指定的aspectJ表达式匹配的类

4.custom:指定expression使用的自定义TypeFilter实现类。

5.regex:正则匹配的类。

4 使用spring基于java的配置

      

4.1 创建基于Java的配置

      <context:component-scan>也会自动加载使用@Configuration注解所标注的类。

4.2 定义一个配置类

      @Configurstion标注的类相当于<Beans>元素。可以包含一个或多个Bean。这些Bean的定义是使用@Bean注解来标注的方法。

4.3 声明一个简单Bean

@Bean public A get(){    return new B();}     @Bean告知spring返回一个对象,该对象应该被注册为spring上下文的一个Bean。方法名为Bean的id。      相对于xml配置来说的一个优点就是,xml是用string类型配置的,编译期无法检查。如果重命名了一个类,或许会完了修改xml配置。

4.4 使用spring的基于Java的配置进行注入

 简单值注入:

@Beanpublic A get(){      return new B(12);}@Beanpublic A get(){      B b =  new B();      b.setName("jack");       return B;}引用注入:

@Beanpublic A get(){      return new B();}@Beanpublic C set(){      return new C(get());}这里调用get()不会调用get()方法而是调用spring上下文中的Bean。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表