Spring核心之Spring bean容器与bean注入

Spring bean容器

Spring Bean 容器(spring 容器(container) 管理 bean的整个生命周期)

Spring IOC 控制反转 DI 依赖注入

Spring AOP 面向切片编程 Aspect Oriented Programing

Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,以供外层的应用程序进行调用。

 

从上图可以清楚的看出 Bean 实现类,Bean配置信息,Spring容器,和Bean调用者之间的关系

 

Spring应用中,应用对象生存于容器(container, spring 容器)中,spring负责创建对象并装配它们,配置它们并管理它们的整个生命周期,从生存到死亡——new到finalize()   ( GC 回收不用的对象)

 

spring容器可归为两类

bean工厂(org.springframework.beans.factory.BeanFactory) 提供简单DI支持

应用上下文(org.springframework.context.ApplicationContext)基于BeanFactory构建,并提供框架服务,如配置解析

 

实例化---->填充属性---->调用BeanNameAware setBeanName()---->调用BeanFactoryAware setBeanFactory()---->调用ApplicationContextAware setApplicationContext()---->调用BeanPostProcessor的预初始化方法---->调用InitializingBean的afterPropertiesSet()方法---->调用自定义的初始化方法---->调用BeanPostProcessor的初始化后方法

至此bean已经可以使用

当容器关闭 ——>调用DisposableBean的destroy()方法——>调用自定义销毁方法——>bean销毁

详细过程:

1.Spring首先对bean进行实例化、

 

2.Spring将值和bean的引用注入到bean对应的属性当中

 

3.如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()

 

4.如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFacotry容器实例传入

 

5.如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来

 

6.如果bean实现了BeanPostProcessor接口,Spring将调用他们的postProcessBeforeInitialization()

 

7.如果bean实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法

 

8.如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()

 

9.Bean准备就绪,驻留在spring应用上下文

 

10.如果bean实现了DisposableBean接口,Spring将调用它的destroy()方法,同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用

 

Bean注入

Bean注入

1、属性注入(setter 注入)

2、构造函数注入

3、工厂方式注入

4、使用注解的方式注入

 

属性注入

属性注入即通过setXxx()方法注入Bean的属性值或依赖对象,由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。

属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。Spring先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。

 

构造方法注入

使用构造函数注入的前提是Bean必须提供带参数的构造函数。

 

工厂方法注入

package com.baobaotao.ditype;

public class CarFactory {
   public Car createHongQiCar(){
       Car car = new Car();
       car.setBrand("红旗CA72");
       return car;
   }
   
   public static Car createCar(){
       Car car = new Car();
       return car;
   }
}

 

使用注解的方式注入

使用@Autowired进行自动注入

Spring通过@Autowired注解实现Bean的依赖注入

 

Spring即使找不到匹配的Bean完成注入也不用抛出异常,那么可以使用@Autowired(required=false)进行标注:

@Autowired(required=false) 

private LogDao logDao;

 

如果容器中有一个以上匹配的Bean时,则可以通过@Qualifier注解限定Bean的名称

//①注入名为userDao,类型为UserDao的Bean 

@Autowired 

@Qualifier("userDao") 

private UserDao userDao;

 

对类方法进行标注

@Autowired可以对类成员变量及方法的入参进行标注,下面我们在类的方法上使用@Autowired注解

@Autowired
    public void init(@Qualifier("userDao")UserDao userDao,LogDao logDao){
        System.out.println("multi param inject");
        this.userDao = userDao;
        this.logDao =logDao;
    }

如果一个方法拥有多个入参,在默认情况下,Spring自动选择匹配入参类型的Bean进行注入。Spring允许对方法入参标注@Qualifier以指定注入Bean的名称

在以上例子中,UserDao的入参注入名为userDao的Bean,而LogDao的入参注入LogDao类型的Bean。

 

补充:

Spring还支持@Resource和@Inject注解,这两个标准注解和@Autowired注解的功能类型,都是对类变量及方法入参提供自动注入的功能。@Resource要求提供一个Bean名称的属性,如果属性为空,则自动采用标注处的变量名或方法名作为Bean的名称。

 

如果@Resource未指定"car"属性,则也可以根据属性方法得到需要注入的Bean名称。可见@Autowired默认按类型匹配注入Bean,@Resource则按名称匹配注入Bean。

 

@Autowired   
private LogDao logXXXDao;  //按类型注入  ByType

@Resource
private UserDao userDao;  // 按名称注入  ByName

 

而@Inject和@Autowired一样也是按类型匹配注入的Bean的,只不过它没有required属性。可见不管是@Resource还是@Inject注解,其功能都没有@Autowired丰富,因此除非必须,大可不必在乎这两个注解。

 

关于Autowired和@Resource

1.@Autowired注入是按照类型注入的,只要配置文件中的bean类型和需要的bean类型是一致的,这时候注入就没问题。但是如果相同类型的bean不止一个,此时注入就会出现问题,Spring容器无法启动。 

2.@Resourced标签是按照bean的名字来进行注入的,如果我们没有在使用@Resource时指定bean的名字,同时Spring容器中又没有该名字的bean,这时候@Resource就会退化为@Autowired即按照类型注入,这样就有可能违背了使用@Resource的初衷。所以建议在使用@Resource时都显示指定一下bean的名字@Resource(name="xxx") 

 

参考:https://www.cnblogs.com/wuchanming/p/5426746.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值