Spring(二)基于注解的方式配置Bean

来源:互联网 发布:什么是淘宝直通车? 编辑:程序博客网 时间:2024/06/05 05:51

Spring通过配置文件或注解的方式完成类和类之间的依赖关系,自动完成类的初始化和依赖注入。

注解可以分成两类:

  • 一类是使用Bean,即把在XML文件中配置好的bean拿来用,完成属性、方法的分装。例如@Autowired,@Resource等
  • 一类是注册Bean,把要实例化的对象转化为一个Bean,存放在IOC容器当中,等待使用。例如@Component等。

注册Bean的注解

  • @Compontent:表示被注释的类是一个组件。可用于任何层次,相当于下面三个注解的并集。
  • @Repository:标识持久层组件
  • @Service:标识服务层(业务层)组件
  • @Controller:标识表现层组件

目前这些组件可以混合使用,IOC容器无法识别这个注解是持久层、业务层还是表现层的。即可以使用@Controller标识持久层,也可以使用@Service标识持久层。但是这样标识会比较混乱,使用特定的组件标识特定的模块可以更加清晰。标识这些注解的Bean相当于在XML配置文件中定义了:

<bean id="xxx" class="XXX"/>

注意:标识组件的Bean如果想要被IOC容器管理还需要在XML中进行激活。

value属性

对于@Component这些组件,Spring有默认的命名策略——使用非限定类名第一个字母小写。

通过value属性改变实例的名称


在XML中激活Bean

<context:annotation-config/>

  • 使用@Autowired,必须在Bean中声明AutowiredAnnotationBeanPostProcessord   Bean
  • 使用@PersistenceContext注解,必须声明PersistenceAnnotationBeanPostProcessor的Bean。
  • 使用 @Required的注解,就必须声明RequiredAnnotationBeanPostProcessor的Bean
  • 使用@ Resource 、@ PostConstruct、@ PreDestroy等注解,必须声明CommonAnnotationBeanPostProcessor的Bean

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

Spring提供了<context:annotation-config/>这个简化配置用于激活Spring容器中注册过的Bean。替换了上面定义的四个Bean。

标上注解的Bean如果要想使用,必须通过扫描注解,获取Bean的定义信息后Bean才可以使用。

<context:component-scan/>

<context:component-scan/>不但具有和<context:annotation-config/>一样的激活组件的功能外,还可以指定某个包下的bean。


<context:component-scan/>中的属性

base-package

说明

1、指定了需要扫描的基类包

2、Spring会扫描基类包以及子包中的所有类

3、如果希望扫描多个包,可以使用逗号分隔多个包

resource-pattern

指定要扫描基类包下的某个特定的类,而非基包下的所有类

context:include-filter

表示要包含的目标类,即白名单

context:exclude-filter

表示要排除在外的目标类,即黑名单

context:include-filter与context:exclude-filter的说明

1、<context:component-scan/>中可以包含多个<context:include-filter/>、<context:exclude-filter/>

2、过滤的类别:

  • annotation:该类型采用目标类是否标注了某个注解进行过滤
  • assignable:该类型采用目标类是否继承或扩展某个特定的类进行过滤
  • aspectj:该类型采用AspectJ表达式进行过滤
  • regex:该类型采用正则表达式根据类的类名进行过滤
  • custom:该类必须实现org.springframework.core.type.TypeFilter接口

例子:

com.gajai.Person.java

package com.gajai;import org.springframework.stereotype.Component;@Componentpublic class Person {public void say(){System.out.println("I am a person");}}
com.gajai.animal.Dog.java

package com.gajai.animal;import org.springframework.stereotype.Repository;@Repositorypublic class Dog {public void say(){System.out.println("Dog is animal");}}

com.gajai.animal.Cat.java

package com.gajai.animal;import org.springframework.stereotype.Service;@Servicepublic class Cat {public void say(){System.out.println("cat is animal");}}
com.gajai.fruit.Apple.java

package com.gajai.fruit;import org.springframework.stereotype.Controller;@Controllerpublic class Apple {public void say(){System.out.println("apple is fruit");}}
applicationContext.xml

<context:component-scan base-package="com.gajai" resource-pattern="animal/*.class"><context:include-filter type="assignable" expression="com.gajai.animal.Dog"/></context:component-scan>

1、扫描base-package基包下的所有注解,即激活了:person,dog,cat,apple这四个Bean。

2、resource-patter指定扫描com.gajai包下的指定的类,即扫描animal包下的所有类,此刻IOC容器中激活了:dog,cat这两个Bean。

3、include-filter中使用assignable类名,指定要包含com.gajai.animal.Dog这个类,即必须包含dog Bean。

所以此刻Spring会扫描com.gajai.animal.Dog、com.gajai.animal.Cat这两个类中的注解,对标注注册Bean的注解进行激活。

运行结果

Dog is animalcat is animal

user-default-filter

注意:<context:component-scan/>中有个默认的属性use-default-filter="true",即自动默认的会对标注了@Component等注解的Bean进行扫描。

修改:添加user-default-filter="false"

<context:component-scan base-package="com.gajai" resource-pattern="animal/*.class"use-default-filters="false"><context:include-filter type="assignable" expression="com.gajai.animal.Dog"/></context:component-scan>
运行结果
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cat' is defined
说明:设置了user-default-filter="false"就不会自动对标注@Component等注解的Bean进行扫描,此刻就需要手动的设置要扫描的Bean,即在include中手动指定要扫描的Bean。


 注解装配Bean

<context:component-scan>元素还会自动的注册AutowiredAnnotationBeanPostProcessor的实例,该实例可以自动装配具有@Autowired、@Resource、@Inject注解的属性。

@Autowired

1、@Autowired注解首先会在IOC容器中查找,看有没有和当前类型兼容的Bean,如果有就直接注入这个bean。即默认按类型加载Bean。 可以放在:构造器、普通字段(非public)、具有参数的方法上

@Qualifier

2、如果IOC容器中有很多与类型配置的Bean,通过类型自动装配将无法完成工作。可以使用@Qualifier注解,提供Bean的名称,Spring会根据标注的Bean名称进行注入。即按名称注入。

required=false

3、当Spring容器中找不到匹配的Bean进行装配时,会抛出异常。若某一个属性允许不被设置,可以设置@Autowired注解的required属性值为false

4、@Autowired

放在数组,Spring将所有匹配的Bean都找出来,并进行装配。

放在集合上,Spring将读取该集合的类型,并且自动装配所有预支兼容的Bean

注解用在java.util.Map上时,使用Bean的名字做键,Bean本身作为值。

@Scope

显示的指定Bean的作用域,默认是singleton


使用@Resource或@Inject自动装配Bean,

这两个与@Autowired功能类似。

@Resource注解要求提供一个Bean名称的属性,如果该属性为空,则自动采用标注出的变量或方法名作为Bean的名称。

@Inject和@Autowired注解一样,也是按照类型匹配注入Bean,但是没有required属性。

建议使用@Autowired




END.

原创粉丝点击