Spring(二)基于注解的方式配置Bean
2017-11-04 19:39
597 查看
Spring通过配置文件或注解的方式完成类和类之间的依赖关系,自动完成类的初始化和依赖注入。
注解可以分成两类:
一类是使用Bean,即把在XML文件中配置好的bean拿来用,完成属性、方法的分装。例如@Autowired,@Resource等
一类是注册Bean,把要实例化的对象转化为一个Bean,存放在IOC容器当中,等待使用。例如@Component等。
注册Bean的注解
@Compontent:表示被注释的类是一个组件。可用于任何层次,相当于下面三个注解的并集。
@Repository:标识持久层组件
@Service:标识服务层(业务层)组件
@Controller:标识表现层组件
目前这些组件可以混合使用,IOC容器无法识别这个注解是持久层、业务层还是表现层的。即可以使用@Controller标识持久层,也可以使用@Service标识持久层。但是这样标识会比较混乱,使用特定的组件标识特定的模块可以更加清晰。标识这些注解的Bean相当于在XML配置文件中定义了:
注意:标识组件的Bean如果想要被IOC容器管理还需要在XML中进行激活。
通过value属性改变实例的名称
在XML中激活Bean
使用@PersistenceContext注解,必须声明PersistenceAnnotationBeanPostProcessor的Bean。
使用 @Required的注解,就必须声明RequiredAnnotationBeanPostProcessor的Bean
使用@ Resource 、@ PostConstruct、@ PreDestroy等注解,必须声明CommonAnnotationBeanPostProcessor的Bean
Spring提供了<context:annotation-config/>这个简化配置用于激活Spring容器中注册过的Bean。替换了上面定义的四个Bean。
标上注解的Bean如果要想使用,必须通过扫描注解,获取Bean的定义信息后Bean才可以使用。
<context:component-scan/>中的属性
1、指定了需要扫描的基类包
2、Spring会扫描基类包以及子包中的所有类
3、如果希望扫描多个包,可以使用逗号分隔多个包
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.animal;
import org.springframework.stereotype.Repository;
@Repository
public class Dog {
public void say(){
System.out.println("Dog is animal");
}
}
com.gajai.animal.Cat.java
package com.gajai.fruit;
import org.springframework.stereotype.Controller;
@Controller
public 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 animal
cat is animal
修改:添加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>运行结果:
4、@Autowired
放在数组,Spring将所有匹配的Bean都找出来,并进行装配。
放在集合上,Spring将读取该集合的类型,并且自动装配所有预支兼容的Bean
注解用在java.util.Map上时,使用Bean的名字做键,Bean本身作为值。
使用@Resource或@Inject自动装配Bean,
这两个与@Autowired功能类似。
@Resource注解要求提供一个Bean名称的属性,如果该属性为空,则自动采用标注出的变量或方法名作为Bean的名称。
@Inject和@Autowired注解一样,也是按照类型匹配注入Bean,但是没有required属性。
建议使用@Autowired
END.
注解可以分成两类:
一类是使用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; @Component public 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;
@Repository
public 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; @Service public 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;
@Controller
public 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 animal
cat 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属性值为false4、@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.
相关文章推荐
- spring(三)(基于注解的方式配置bean)
- Spring基于注解的方式配置bean的实例
- Spring中Bean的配置:基于注解的方式
- Spring_基于注解的方式配置bean
- [原创]java WEB学习笔记103:Spring学习---Spring Bean配置:基于注解的方式(基于注解配置bean,基于注解来装配bean的属性)
- Spring笔记2-基于注解的方式配置Bean
- Spring使用注解的方式配置bean的属性-bean之间的引用关系
- 04-Spring-使用ioc注解方式配置bean
- Springboot 中同时使用mybatis注解和springbean-xml配置方式
- Spring(三):IoC容器装配Bean(xml配置方式和注解方式)
- spring 11 bean配置-基于注解配置bean
- spring知识四------基于注解的配置bean
- 基于Spring注解方式配置Quartz
- Spring4 学习笔记(3)-Spring 基于 XML 的方式配置 Bean
- Spring配置文件中bean标签中init-method和destroy-method和用注解方式配置
- Spring AOP基于注解的“零配置”方式实现以及一些其他知识点
- spring 注解方式配置Bean
- Spring学习03 基于注解配置Bean
- Spring学习(15)--- 基于Java类的配置Bean 之 @Bean & @Scope 注解
- Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析