- classpath扫描与组件管理
- 类的自动检测与注册bean
- <context:annotation-config>
- @Component, @Repository, @Service, @Controller
- @Required
- @Autowired
- @Qualifier
- @Resource
一、Classpath扫描与组件管理
从spring3.0开始,Spring JavaConfig项目提供了许多特性,包括使用Java而不是XML来定义bean,比如@Configuration,@Bean,@Import,@DependsOn。
@Component是一个通用注解,可用于任何bean,@Repository,@Service,@Controller是根据有针对性的注解。
- @Repository通常用于DAO类,即持久层
- @Service通常用于注解Service类,即服务层
- @Controller通常用于注解Controller类,即控制层(MVC)
二、类的自动检测即bean的注册
Spring可以自动检测类并注册bean到ApplicationContext(IOC容器)中。
<context:annotation-config>仅会查找在同一个applicationContext中的bean注解。为了让spring能够检测到这些类并注册相应的bean,需要在spring配置文件中添加<context:component-scan>,<context:component-scan>已经包含<context:annotation-config>,通常在使用前者后不再使用后者。<context:component-scan>会扫描使用了@Repository,@Service,@Controller注解的类,并把它们加入到容器中去。
三、使用过滤器进行自定义的扫描
默认情况下,类被自动发现并注册bean的条件是:使用了@Repository,@Service,@Controller,@Component。但是可以通过过滤器修改自动发现的行为。
1 、在主容器中(applicationContext.xml),将Controller的注解打消掉
<context:component-scan base-package="exampleBean">
<context:exclude-filter type="annotation"expression="org.springframework.stereotype.Controller" />
</context:component-scan>
2 、在主容器中(applicationContext.xml),按正则过滤指定类
<context:component-scan base-package="exampleBean">
<!-- 过滤掉exampleBean下的且类名以Default开头的类 -->
<context:exclude-filter type="regex" expression="exampleBean\.Default*" />
</context:component-scan>
3 、在主容器中(applicationContext.xml),按指定类名过滤指定类
<context:component-scan base-package="exampleBean">
<!-- 过滤掉exampleBean下的类名为<span style="font-family: Arial, Helvetica, sans-serif;">MovieFinder</span>的类 -->
<context:exclude-filter type="assignable" expression="exampleBean.MovieFinder"/>
</context:component-scan>
四、定义Bean与作用域
扫描过程中组件被自动检测,那么Bean名称是由BeanNameGenerator生成的(@Repository,@Service,@Controller,@Component都会有个name属性用于显式的设置Bean Name)。
我们也可以自定义bean命名策略,实现BeanNameGenerator接口,并一定要包含一个无参数构造函数。
通常情况下自动查找的spring组件,其scope默认是singleton,但是从spring2.5之后,提供了一个标识scope的注解@Scope,使用方法如@Scope("prototype")。也可以自定义scope策略,实现ScopeMetadataResolver接口并提供一个无参构造器。
五、@Required、@Autowired、@Qualifier、@Resource注解
@Required注解适用于bean属性的setter方法,这个注解仅仅表示,受影响的bean属性必须在配置时被填充,通过在bean定义或通过自动装配一个明确的属性值。也就是说,bean的属性在配置的时候就被赋值。在应用中不常用。
@Autowired最常用。默认情况下,如果因找不到合适的bean将会导致autowiring失败抛出异常,可以通过@Autowired(required=false)方式避免。每个类只能有一个构造器被标记为required=false。可以使用@Autowired注解放在setter方法来摆脱在XML配置文件中的<property>元素。当Spring发现setter方法使用@ Autowired注解,它会尝试对方法进行byType的自动装配。我们可以使用@Autowired注解那行总所周知的解析依赖性接口,比如:BeanFactory,ApplicationContext,Environment,ResourceLoader,ApplicationEnventPublisher,和MessageSource。@Autowired是由SpringBeanPostProcessor处理的,所以不能在自己的BeanPostProcessor或BeanFactoryPostProcessor类型应用这些注解,这些类型必须通过XML或者Spring的@Bean注解加载。
Spring 注解实例--@Autowired 注入到List和Map
@Qualifier注解:按类型自动装配可能多个bean实例的情况,也可以使用Spring的@Qualifier注解缩小范围(或者指定唯一),也可以用于指定单独的构造器参数或方法参数。可用于注解集合类型变量。
如果通过名字进行注解注入,主要使用的不是@Autowired(即使在技术上能够通过@Qualifier指定bean的名字),替代方法是使用JSR-250@Resource注解,它是通过其独特的名称来定义和识别特定目标(这是一个与所声明的类型是无关的匹配过程)。
@Autowired是根据类型进行自动装配的。如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使用@Qualifier配合@Autowired来解决这些问题。可能存在多个UserDao实例
@Autowired
@Qualifier("userServiceImplOne")
public IUserService userServiceOne;
@Autowired
@Qualifier("userServiceImplTwo")
public IUserService userServiceTwo;
@Bean标识一个用于配置和初始化一个由SpringIOC容器管理的新对象的方法,类似于XML配置文件的<bean/>,可以在Spring的@Component注解的类中使用@Bean注解任何方法。通常和@Bean一同使用的是@Configuration.
@Resource
当咱们需要在某个类中定义一个属性,并且该属性是一个已存在的 bean,在为该属性赋值或注入的时候,就需要在该属性的上一行添加一个 @Resource 注解,即
@Service
public class YeepayService(){
@Resource(name="yeePay")
private YeePay yeePay;
public static void sayHi(){
System.out.println("你好啊");
}
}
在这里,@Resource(name=”XXX”),就相当于为该属性注入一个名称为 XXX 的 bean。