数值,我们就可以在这个方法实现中将null值转换为特定的值
3.2.3:BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)。可以在这个方法中进行bean的实例化之后的处理,比如我们的自定义注解,对依赖对象的版本控制自动路由切换。比如有一个服务依赖了两种版本的实现,我们如何实现自动切换呢?这时候可以自定义一个路由注解,假如叫@RouteAnnotaion,然后实现BeanPostProcessor接口,在其中通过反射拿到自定义的注解@RouteAnnotaion再进行路由规则的设定。
3.2.4:SmartInitializingSingleton.afterSingletonsInstantiated
4.1:容器启动运行阶段
4.1.1:SmartLifecycle.start
容器正式渲染完毕,开始启动阶段,bean已经在spring容器的管理下,程序可以随时调用
5.1:容器停止销毁
5.1.1:SmartLifecycle.stop(Runnable callback)
spring容器停止运行
5.1.2:DisposableBean.destroy()
spring会将所有的bean销毁,实现的bean实例被销毁的时候释放资源被调用
四:一些关键性的问题
4.1:FactoryBean和BeanFactory的区别?
BeanFactory是个bean 工厂类接口,是负责生产和管理bean的工厂,是IOC容器最底层和基础的接口,spring用它来管理和装配普通bean的IOC容器,它有多种实现,比如AnnotationConfigApplicationContext、XmlWebApplicationContext等。
FactoryBean是FactoryBean属于spring的一个bean,在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,是一个可以生产对象和装饰对象的工厂bean,由spring管理,生产的对象是由getObject()方法决定的。注意:它是泛型的,只能固定生产某一类对象,而不像BeanFactory那样可以生产多种类型的Bean。在对于某些特殊的Bean的处理中,比如Bean本身就是一个工厂,那么在其进行单独的实例化操作逻辑中,可能我们并不想走spring的那一套逻辑,此时就可以实现FactoryBean接口自己控制逻辑。
4.2:spring如何解决循环依赖问题
循环依赖问题就是A->B->A,spring在创建A的时候,发现需要依赖B,因为去创建B实例,发现B又依赖于A,又去创建A,因为形成一个闭环,无法停止下来就可能会导致cpu计算飙升
如何解决这个问题呢?spring解决这个问题主要靠巧妙的三层缓存,所谓的缓存主要是指这三个map,singletonObjects主要存放的是单例对象,属于第一级缓存;singletonFactories属于单例工厂对象,属于第三级缓存;earlySingletonObjects属于第二级缓存,如何理解early这个标识呢?它表示只是经过了实例化尚未初始化的对象。Spring首先从singletonObjects(一级缓存)中尝试获取,如果获取不到并且对象在创建中,则尝试从earlySingletonObjects(二级缓存)中获取,如果还是获取不到并且允许从singletonFactories通过getObject获取,则通过singletonFactory.getObject()(三级缓存)获取。如果获取到了则则移除对应的singletonFactory,将singletonObject放入到earlySingletonObjects,其实就是将三级缓存提升到二级缓存,这个就是缓存升级。spring在进行对象创建的时候,会依次从一级、二级、三级缓存中寻找对象,如果找到直接返回。由于是初次创建,只能从第三级缓存中找到(实例化阶段放入进去的),创建完实例,然后将缓存放到第一级缓存中。下次循环依赖的再直接从一级缓存中就可以拿到实例对象了。
五:测试
我们来写一个测试类,验证一下上面的问题:
5.1:首先声明一个自定义的Bean
@Component
public class CustomBean {
public CustomBean(){
System.out.println("调用CustomBean空的构造方法");
}
}
5.2:声明一个Bean来实现BeanPostProcessor
package com.wyq.spring.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* @Author: wyq
* @Desc:
* @Date: 2019/9/1 15:36
**/
@Component
@Scope("singleton")
public class TestBean implements BeanPostProcessor, SmartInitializingSingleton, InstantiationAwareBeanPostProcessor, DisposableBean{
private static final String BEAN_NAME= "customBean";
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (BEAN_NAME.equals(beanName)) {
System.out