java springMVC web容器啟動時初始化方法
阿新 • • 發佈:2018-12-26
需求:在tomcat服務啟動時初始化一些引數。
想法:容器啟動時執行方法,最容易想到的就是servlet中可以配置load-on-startup,設定一個正整數也就可以隨容器一起啟動。
解決方案:Spring提供了當一個Bean初始化後執行方法的擴充套件點:InitializingBean。這裡的初始化指的就是當該Bean的屬性被注入完成後(注意:這裡並不是所有屬性都需要被設定),所以InitializingBean介面提供的方法名稱也很形象:afterPropertiesSet()。
@Component
public class InitServlet implements InitializingBean {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void afterPropertiesSet() throws Exception {
//在這裡面進行操作
}
}
另外還有兩種方法也可以實現如上的功能。
若採用XML來配置Bean的話,可以指定屬性init-method
通過註解@PostConstruct來修改初始化方法
這裡我們舉例說明一下@PostConstruct在程式碼中的用法
@Service("AjaxCacheableService")
public class AjaxCacheableService{
/**
* 構造方法執行後,初始化,
*/
@PostConstruct
public void init() {
//程式碼寫在這裡
}
}
Spring中呼叫Bean的初始化程式碼的原始碼:
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>() {
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();// 這裡觸發afterPropertiesSet
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();<span style="white-space:pre"> </span>// 這裡觸發afterPropertiesSet
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();// 這裡是觸發init-method
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
從這裡可以看出,三者可以同時存在,觸發的順序是先觸發@PostConstruct修飾的方法,再觸發afterPropertiesSet(),最後觸發init-method
其中@PostConstruct是通過註冊一個BeanPostProcessor,在Bean的初始化方法之前呼叫,而afterPropertiesSet()和init-method都在初始化方法中呼叫。