DI依赖注入_手动装配_注解基础
以下的注释不管在那种配置组件的方法中都能用,这里只是实际需要才这么放的
用bean定义来配置组件
首先需要在xml 文件中添加如下 spring-context-3.0.xsd 文件
<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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> </bean>
<context:annotation-config /> <!--打开注解,注册处理器-->
这个配置隐式注册了多个对注释进行解析处理的处理器 AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor, RequireAnnotationBeanPostProcessor
@Autowired 注释
它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作(将bean的实例装到相应位置)
@Autowired 根据 类型从spring 配置文件中进行查找,注册类型必须唯一,否则报异常。
默认情况下它要求依赖对象必须存在,如果允许null,可以设置required属性为false
@Autowired(required = false)
private ISoftPMService softPMService = new SoftPMServiceImpl();
与@Resource 的区别在于,@Resource 允许通过bean 名称或bean 类型两种方式进行查找
将@Autowired 注释标注在成员变量上
import org.springframework.beans.factory.annotation.Autowired;
public class Boss {
@Autowired
private Car car;
@Autowired
private Office office;
…
}
spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用
必须事先在 Spring 容器中声明AutowiredAnnotationBeanPostProcessorBean。
<!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 --> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
这样,当Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描spring 容器中所有 Bean,
当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的Bean,并注入到对应的地方中去。
按照上面的配置,Spring 将直接采用 Java 反射机制对 Boss 中的 car 和 office 这两个私有成员变量进行自动注入。
所以对成员变量使用 @Autowired 后,大可将它们的 setter 方法删除。
通过 @Autowired 对方法或构造函数进行标注
将 @Autowired 注释标注在 Setter 方法上
public class Boss {
private Car car;
private Office office;
@Autowired
public void setCar(Car car) {
this.car = car;
}
@Autowired
public void setOffice(Office office) {
this.office = office;
}
…
}
这时,@Autowired 将查找被标注的方法的入参类型的 Bean,并调用方法自动注入这些 Bean。
将@Autowired 注释标注在构造函数上
public class Boss {
private Car car;
private Office office;
@Autowired
public Boss(Car car ,Office office){
this.car = car;
this.office = office ;
}
…
}
由于 Boss() 构造函数有两个入参,分别是 car 和 office,@Autowired 将分别寻找和它们类型匹配的 Bean,
将它们作为 Boss(Car car ,Office office) 的入参来创建 Boss Bean
实例:引用上一篇的实例
在xml中配置
<bean id="dao" class="com.qh.daoImp.daoImp"></bean>
<bean id="serviceImp" class="com.qh.serviceImp.ServiceImp"></bean>
ServiceImp.java
package com.qh.serviceImp;
import javax.annotation.Resource;
import com.qh.dao.Dao;
import com.qh.service.Service;
public class ServiceImp implements Service {
@Autowired //获取 Dao 字段,查找xml文件中的bean,找到 com.qh.daoImp.daoImp 这个类
private Dao dao;
private String name;
public ServiceImp(){}
public void say(){
System.out.println(name);
dao.add();
}
}
注意:最好给ServiceImp类一个默认的构造方法
我们可以通过 @Qualifier 强制将 @Autowired 默认的查找方式改为 按照bean名称 查找
@Qualifier
@Autowired 可以对成员变量、方法以及构造函数进行注释,而 @Qualifier 的标注对象是成员变量、方法入参、
构造函数入参。正是由于注释对象的不同,所以 Spring 不将 @Autowired 和 @Qualifier 统一成一个注释类。
@Autowired @Qualifier("dao")
@Qualifier 只能和 @Autowired 结合使用,是对 @Autowired 有益的补充。一般来讲,
@Qualifier 对方法签名中入参进行注释会降低代码的可读性,而对成员变量注释则相对好一些。
@Resource注释
@Resource 默认按bean 的name 进行查找,如果没有找到,会按type 进行查找,此时与@Autowired 类似
@Resource有一个name属性,可以根据name属性值查找对应的bean的id
在classpath自动扫描方式进行注解(解决用bean配置使文件过大问题)
原理:组件自动扫描机制,自动扫描类路径下标注了
@Controller:标注控制层组件(如struts中的action)
@Service:标注业务逻辑层组件
@Component :泛指组件,当组件不好归类的时候,可以用这个标注(不推荐使用)
@Repository:标注数据访问组件,即dao层
注释的类
首先需要在xml 文件中添加如下 spring-context-3.0.xsd 文件
<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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> </bean>
<context:component-scan base-package="com.qh"/> <!--此配置注册了包括<context:annotation-config />在内的处理器-->
base-package属性为需要扫描的包(包括子包)
然后在相应的层上标注即可
注意:bean 的ID 默认为类名称开头字母小写; 修改bean的名称:@Controller("cat")表示bean的名称为 cat
@Controller
@Controller的基本目标是担任所注解的类的原型的角色,指明它的职责。
Dispatcher将会在这样被注解的类中扫描映射的方法,探测注解@RequestMapping。
所注解的控制器bean可以被显式定义,这个过程是在Dispatcher的上下文中使用标准的Spring bean定义完成的。
然而,@Controller原型也允许自动探测。
@Service、@Component 、@Repository和@Controller类似
@scope:bean的作用范围(prototype、单例等)
例如:@Service @scop("prototype")
@PostConstruct(相当于 init-method方法)
在方法上加上注解@PostConstruct ,这个方法就会在Bean 初始化之后被Spring 容器执行(注:Bean 初始化包括,实例化Bean ,并装配Bean 的属性(依赖注入))。
@PreDestroy( 相当于 destroy-method 方法)
在方法上加上注解@PreDestroy ,这个方法就会在Bean 被销毁前被Spring 容器执行。