让Father类实现InitializingBean, DisposableBean接口,并实现下面两个方法,自定义内容的输出。并手动创造初始化法和销毁方法,还依赖注入Son对象。
package com.csc.pojo;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 自定义的Father类
*/
@Component
public class Father implements InitializingBean, DisposableBean {
@Autowired
private Son son;
@PostConstruct
public void initMethod(){
System.out.println("Father...initMethod...执行了...");
}
@PreDestroy
public void destroyMethod(){
System.out.println("Father...destroyMethod...执行了...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean...afterPropertiesSet...执行了...");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean...destroy...执行了...");
}
}
自定义的Son类。
package com.csc.pojo;
import org.springframework.stereotype.Component;
/**
* 自定义的Son类
*/
@Component
public class Son {
}
自定义的bean的后置处理器。
package com.csc.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* bean的后置处理器,当bean对象初始化之前和之后都会调用下面两个方法
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
//初始化之前调用
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor...postProcessBeforeInitialization..."+beanName);
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
//初始化之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor...postProcessAfterInitialization..."+beanName);
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
接上一篇文章IOC容器初始化的流程,其中this.finishBeanFactoryInitialization(beanFactory)就是创建单例非懒加载的实例。
首先,我们要明确要看的代码,其次,与目标代码无关的最好不要看防止干扰,最后要根据中文名字来猜测相关的英文单词。
1.步入进来,该方法里面有许多代码,根据上面方法发现beanFactory.preInstantiateSingletons(),应该就是预实例化单例bean。
2.步入进去发现里面有个beanDefinitionNames集合,beanDefinition就是存储bean的信息,从里面可以看到我们自定义bean的名字,有father和son等等。
3.步过,发现这是循环实例化非懒加载单实例bean,我们在729行打上断点,一直放行找到我们自定义的father类,看debug有个beanName就是实例的bean名字。
4.然后步过跳转到了this.getBean(beanName),这个就是获取bean实例。
5.步入进去,看见了doGetBean(),就是真正获取bean实例的方法了。
6.再步入,发现该方法代码也是一样非常非常多,非常复杂,但是按看代码原则去寻找,应该可以快速找到相应的代码。
7.找到了下面代码。发现该段代码就是获取单例bean的方法,包含了bean的名字和一个lamda表达式,其中重点就是lamda表达式里面的内容。
8.步入getSingleeton(),发现133行代码的singletonFactory就是getSingleeton()里面的一个参数,也就是lamda表达式的值。
9.步入,就是会跳转到lamda表达式里面了,发现了createBean()应该就是创建bean实例了。
10.步入,找创建bean相关的代码,doCreateBean()就是核心创建bean的代码。
11.其中BeanWrapper就是bean实例的包装对象,作用就是为bean实例提供很多方法,方便操作,例如属性的获取,设置等等,类似反射。
12.这个就是最终创建bean实例,这个方法底层就是通过反射来创建的,没必要再步入看bean怎么创建的了,以及快到jdk级别了,没有意义步入进去了。
13.最终就可以发现这个bean就是father。至此,bean实例化已经结束。
1.现在已经创建好了father对象,但是son并没有依赖注入,接下来就是看怎么依赖注入的。
3.步过,发现就是依赖注入好了,可以看exposedObject对象,有了son这个bean实例了。
1.这个就是初始化的方法。
2.其中的invokeAwareMethods()就是执行Aware接口回调,就是感知接口。
3.执行BeanPostProcessors,PostProcessorsBeforeInitialization两个方法。可以看到控制台输出的内容。一个就是bean的后置处理器,一个就是手动添加的初始化,通过@PostConstruct就可以知道是手动添加的,然后自动处理。
5.执行BeanPostProcessors,PostProcessorsBeforeInitialization两个方法。
6.最后返回创建好的WrappedBean。至此,bean的初始化就到此结束了。
7.还有个细节,我们发现son其实已经创建好了,为什么呢?在father创建的时候,需要依赖注入son实例,所以就会创建好son实例。所以在创建son实例的时候,会直接返回,并不会再创建。
这就是程序员自己去使用了。
停止运行spring,控制台输出,先执行@PreDestroy,后执行BeanPostProcessor。
参考黑马程序员的图,如下图所示: