InitializingBean接口
InitializingBean接口概述
spring提供了initializingBean接口为bean提供了初始化后的处理方法,内部提供了 afterPropertiesSet()方法,凡是实现改接口的类,初始化的时候都会执行该方法,源码如下:
package org.springframework.beans.factory;
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
InitializingBean在spring源码中的应用
在spring源码的AbstractAutowireCapableBeanFactory类中的invokeInitMethods()方法中, 源码如下:
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends
AbstractBeanFactory implements AutowireCapableBeanFactory {
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
/**
* 判断是不是实现了InitializingBean接口 , 如果是调用afterPropertiesSet方法
* 如果不是,则调用invokeCustomInitMethod自定义初始化方法 (反射方式调用 init-method)
*/
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
}
分析上面代码可以发现spring为我们提供了两种初始化bean的方法。第一种是实现InitializingBean接口的afterPropertiesSet方法;第二种是通过@Bean的init-method指定初始化方法。
第一种方式的效率会比第二种低一些,但耦合度比第二种方式要高。两者也可以结合使用。
DisposableBean接口
DisposableBean接口概述
实现DispoableBean接口的类会在销毁bean之前执行该接口中的destroy方法,源码如下:
package org.springframework.beans.factory;
public interface DisposableBean {
/**
* Invoked by the containing {@code BeanFactory} on destruction of a bean.
* @throws Exception in case of shutdown errors. Exceptions will get logged
* but not rethrown to allow other beans to release their resources as well.
*/
void destroy() throws Exception;}
在Bean的声明周期结束之前调用destroy方法来做一些收尾的工作,也可以使用@Bean注解的destroy-method属性来指定销毁方法。两者之间的优劣和初始化方法的一样。
DisposableBean的destroy方法一般针对单例对象,多例对象事项DisposableBean接口也没有意义,相应的方法也不会被调用,在多例Bean的情况下,spring不会自动调用bean的销毁方法。