上面两篇文章分别介绍了spring生命周期中初始化和销毁的几种方式以及统一后置BeanPostProcessor接口的使用,可以点击以下链接查看:
今天我们就来一起看看spring底层是如何实现这些的,在看它的实现原理之前,我们再来把之前几种方式结合放一个例子中演示下
新建一个User1对象如下:
/**
* 定义一个实现InitializingBean DisposableBean的bean
*
* @author zhangqh
* @date 2018年5月4日
*/
public class User1 implements InitializingBean,DisposableBean{
public User1(){
System.out.println("实例化User1的构造方法......");
}
public void destroy() throws Exception {
System.out.println("调用实现DisposableBean的destroy方法....");
}
public void afterPropertiesSet() throws Exception {
System.out.println("调用实现InitializingBean的afterPropertiesSet方法......");
}
public void initUser(){
System.out.println("执行initMethod方法.....");
}
public void destroyUser(){
System.out.println("执行destroyMethod方法......");
}
}
新建一个MyBeanPostProcessor实现BeanPostProcessor如下:
/**
* 定义一个前置后置处理器
*
* @author zhangqh
* @date 2018年5月6日
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
// 这边只做简单打印 原样返回bean
System.out.println("postProcessBeforeInitialization===="+beanName);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
// 这边只做简单打印 原样返回bean
System.out.println("postProcessAfterInitialization===="+beanName);
return bean;
}
}
主配置文件如下:
/**
* 定义一个注解配置文件 必须要加上@Configuration注解
*
* @author zhangqh
* @date 2018年4月30日
*/
@Configuration
public class MainConfig {
@Bean(initMethod="initUser",destroyMethod="destroyUser")
public User1 getUser1(){
return new User1();
}
@Bean
public MyBeanPostProcessor getMyBeanPostProcessor(){
return new MyBeanPostProcessor();
}
}
测试代码如下:
public static void main(String[] args) {
// 使用AnnotationConfigApplicationContext获取spring容器ApplicationContext2
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);
applicationContext2.close();
}
运行结果如下:
实例化User1的构造方法......
postProcessBeforeInitialization====getUser1
调用实现InitializingBean的afterPropertiesSet方法......
执行initMethod方法.....
postProcessAfterInitialization====getUser1
调用实现DisposableBean的destroy方法....
执行destroyMethod方法......
从结果中可以看出他们之前执行的顺序如下:注意其中的位置序号下边文章会用到
1,首先执行bean的构造方法,
2,BeanPostProcessor的postProcessBeforeInitialization方法
3,InitializingBean的afterPropertiesSet方法
4,@Bean注解的initMethod方法
5,BeanPostProcessor的postProcessAfterInitialization方法
6,DisposableBean的destroy方法
7,@Bean注解的destroyMethod方法
接下来我们再来看看spring底层的实现,首先进入程序的启动类AnnotationConfigApplicationContext方法如下:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
里边有两个方法一个是register注册对应的java配置类和另一个是refresh方法,我们重点来看这个refresh方法如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 省略大部分代码
// 实例化所有的不是延迟加载(延迟加载的只有在使用的时候才会实例化)的bean实例
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}catch (BeansException ex) {
// 省略部分代码
}finally {
resetCommonCaches();
}
}
}
接下来我们重点来看下finishBeanFactoryInitialization实例化bean的方法,进去之后我们发现最后有一个preInstantiateSingletons方法如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 省略大部分代码
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
继续查看preInstantiateSingletons对应实现如下:
@Override
public void preInstantiateSingletons() throws BeansException {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 循环所有的bean实例化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// 获取bean方法
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
// 省略部分代码
}
我们发现里边的关键方法getBean如下:
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
继续跟进去如下:
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// 检查缓存中是否已经存在了bean实例.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}else {
// 省略部分代码。。。。。
try {
// 省略部分代码。。。。。
// 判断bean是否配置的是单实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}// bean配置的是多实例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {// 既不是单实例也不是多实例的逻辑
// 省略部分代码。。。。。
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 省略部分代码。。。。。
return (T) bean;
}
接下来重点看一下其中创建bean的方法createBean如下:
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 省略部分代码
// 重点注意doCreateBean方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
继续跟进可以看到doCreateBean方法如下:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// 省略部分代码
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 省略部分代码......
// Register bean as disposable.
// 注意这个地方 下面讲销毁的时候说讲到
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
可以发现其中有一个initializeBean方法如下:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 省略部分代码。。。。
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 重点来了BeanPostProcessor的postProcessBeforeInitialization方法执行的地方
// 这也是为什么他执行所有的初始化之前的原因了
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 初始化bean
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor的PostProcessorsAfterInitialization方法执行的地方
// 初始化完成之后执行BeanPostProcessor的postProcessorsAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
到这BeanPostProcessor的实现已经很清晰了吧,BeanPostProcessor的postProcessBeforeInitialization(方法位置2)和BeanPostProcessor的postProcessAfterInitialization(方法位置5)的执行位置我们搞清楚了,那上面的位置3和位置4又是怎么执行的呢,让我们继续到invokeInitMethods里边看看如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 位置3的 InitializingBean的afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
// 位置4的 @Bean注解的initMethod方法
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
聪明的你应该一眼就能看到位置3,以及位置4的执行顺序了吧
好了初始化的逻辑部分搞清楚了,接下来我们一起来看看销毁的流程,销毁开始于applicationContext.close();方法,点进去看如下:
@Override
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
看到其中有一个doClose继续跟进去看会发现有一个destroyBeans方法,再进去直到找到destroySingletons方法如下:
public void destroySingletons() {
// 省略部分代码
// 循环所有的disposableBean执行对应的destroy方法
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
// 省略部分代码
}
在继续从destroySingleton方法进去可以找到destroyBean方法如下:
protected void destroyBean(String beanName, DisposableBean bean) {
// 省略部分代码
// 重点的地方到了 执行DisposableBean 中的destroy 也就是位置6 中对应的打印
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
// 省略部分代码
}
到这里我们已经完成了90%的原理分析了,这个时候细心的你一定会发现那位置7中的@Bean注解中配置的destroyMethod是在什么时候调用的呢,好像上面都没有讲到,要想知道destroyMethod的调用让我们回到上面讲bean初始化中的doCreateBean方法中其中有一个registerDisposableBeanIfNecessary方法进去看如下:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
// 关键代码
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
继续进去到DisposableBeanAdapter类如下:
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
this.destroyMethod = determineDestroyMethod();
if (this.destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Couldn't find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
Class<?>[] paramTypes = this.destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
怎么样,到现在是不是就很清晰了,位置7的打印其实也是DisposableBean方法中打印出来的,@bean注解的destroyMethod其实是在初始化的时候转换成DisposableBean的实现放入到了disposableBeans中
到此今天所有内容就到此结束了,最后以一张流程图总结下如下:
以上是今天文章的所有内容,欢迎大家吐槽