1、简介
Spring容器默认禁用注解装配。所以在基于注解的自动装配前,我们需要再Spring配置中启用它。
注册注解处理器:
方式一:bean
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
方式二: 命名空间<context:annotation-config />
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
</beans>
<context:annotation-config /> 将隐式地向Spring容器注册AutowiredAnnotationBeanPostProcessor 、CommonAnnotationBeanPostProcessor 、 PersistenceAnnotationBeanPostProcessor 以及RequiredAnnotationBeanPostProcessor 这4个BeanPostProcessor 。
Spring3的基于注解实现Bean依赖注入支持如下三种注解:
Spring自带依赖注入注解: Spring自带的一套依赖注入注解;如:@Autowired注解
JSR-250注解:Java平台的公共注解,是Java EE 5规范之一,在JDK6中默认包含这些注解,从Spring2.5开始支持。
JSR-330注解:Java 依赖注入标准,Java EE 6规范之一,可能在加入到未来JDK版本,从Spring3开始支持;如@Resource注解
注: @Resource注解在spring安装目录的lib\j2ee\common-annotations.jar
JPA注解:用于注入持久化上下文和实体管理器。
2、@Autowired
@Autowired 默认按类型装配,类似于自动装配
<!-- 通过构造器参数索引方式依赖注入 -->
<bean id="byIndex" class="cn.javass.spring.chapter3.HelloImpl3">
<constructor-arg index="0" value="Hello World!"/>
<constructor-arg index="1" value="1"/>
</bean>
<!-- 使用自动装配方式依赖注入 -->
<!-- 不需要配置constructor-arg依赖注入了 -->
<bean id="byIndex" class="cn.javass.spring.chapter3.HelloImpl3" autowire="byType"/ >
<!-- 使用注解方式依赖注入 -->
<!-- 不需要配置 autowire="byType" -->
<context:annotation-config/>
<bean id="byIndex" class="cn.javass.spring.chapter3.HelloImpl3" / >
2.1 在字段属性上使用@Autowired
@Autowired //从xml文件中寻找到类型为PersonDao的bean后初始化personDao
private PersonDao personDao;//用于字段上
2.2 在方法上使用@Autowired
//用于属性的set方法上
@Autowired
public void setPersonDao(PersonDao personDao)
{
this.personDao = personDao;
}
//用于普通方法上
@Autowired
public void print(PersonDao personDao)
{
this.personDao = personDao;
}
2.3 在构造器上使用@Autowired
@Autowired
public PersonInfo(PersonDao personDao)
{
this.personDao = personDao;
}
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如:@Autowired(required=false)
使用@Autowired 时,如果找到多个同一类型的bean,则会抛异常,此时可以使用 @Qualifier("beanName"),明确指定bean的名称进行注入。
如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired
@Qualifier("personDao")
private PersonDao personDao;//用于字段上
//用于属性的set方法上
@Autowired
public void setPersonDao(@Qualifier("personDao") PersonDao personDao) {
this.personDao= personDao;
}
3、@Resource
@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上.
@Resource注解默认按名称装配。名称可以通过@Resource的name属性指定。
如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象
当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
//从xml文件中寻找到名字为personDao的bean后初始化personDao
//用于字段上
@Resource(name="personDao")
private PersonDao personDao;
//用于属性的set方法上
@Resource(name="personDao")
public void setPersonDao(PersonDao personDao)
{
this.personDao = personDao;
}
后一种相当于xml配置文件中的<property name=“personDao" ref="personDao" />
注意:如果没有指定name属性,并且按照默认的名称找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。
4、自动检测Bean
<context:annotation-config />有助于完全消除Spring配置中<property> 和 <constructor-arg>,但我们仍需要使用<bean>元素显示定义Bean。
Spring还有另一种技巧<context:component-scan>元素除了完成<context:annotation-config >一样的工作,还允许Spring自动检测Bean和定义Bean,这以为着可以不使用<bean>元素,Spring应用中的大多数(或者所有)Bean都能够实现定义和装配。
spring2.5为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。
要使用自动扫描机制,我们需要打开以下配置信息:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="包路径" >
<context:include-fileter type="类型" expression="匹配" /> <!--包含匹配-->
<context:exclude-filter type="类型" expression="匹配路径" /> <!--排除匹配-->
</context:component-scan>
</beans>
base-package为需要扫描的包(含子包),他会将这些包下的类自动扫描按需装配成bean,并且bean的名字为该类的类名,但首字母小写。
1、在使用组件扫描元素时,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor会隐式地被包括进来。 也就是说,这个组件都会被自动检测并注入 - 所有这一切都不需要在XML中提供任何bean配置元数据。
2、功能介绍
@Service用于标注业务层组件、
@Controller用于标注控制层组件(如struts中的action)、
@Repository用于标注数据访问组件,即DAO组件。
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
//HibernateUtil
@Component //指定该类为Component组件
public class HibernateUtil {
//从xml文件中寻找到名字为sessionFactory的bean后初始化sessionFactory
@Resource(name = "sessionFactory")
private SessionFactory factory;
//该属性可以无get/set 方法
....
}
//Dao层
import org.springframework.stereotype.Repository;
import com.test.dao.PersonDao;
@Repository //指定该类为Repository组件
public class PersonDaoBean implements PersonDao {
//即默认取字段的名称作为bean名称寻找依赖对象,即hibernateUtil
@Resource
private HibernateUtil hibernateUtil;
....
}
//业务层/Service层
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.test.dao.PersonDao;
import com.test.service.PersonService;
@Service //指定该组件为Service组件
public class PersonServiceBean implements PersonService {
@Resource //即默认取字段的名称作为bean名称寻找依赖对象
private PersonDao personDao;
....
}
//控制层/Controller层
@Controller//指定该组件为Controller组件
public class AccountMngAction
{
//即默认取字段的名称作为bean名称寻找依赖对象
@Resource
private CheckInBiz checkInBiz;
@Resource
private RoomBiz roomBiz;
@Resource
private AccountBiz accountBiz;
....
}
参考来源:
Spring学习3—控制反转(IOC)基于Annotation(注解)的依赖注入实现