欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

DI依赖注入_手动装配_注解基础

程序员文章站 2022-05-23 21:47:00
...

以下的注释不管在那种配置组件的方法中都能用,这里只是实际需要才这么放的

用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 容器执行。