spring啟動(dòng)加載程序的幾種方法介紹
關(guān)于在spring 容器初始化 bean 和銷毀前所做的操作定義方式有三種:
第一種:通過注解@PostConstruct 和 @PreDestroy 方法 實(shí)現(xiàn)初始化和銷毀bean之前進(jìn)行的操作
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class DataInitializer{
@PostConstruct
public void initMethod() throws Exception {
System.out.println("initMethod 被執(zhí)行");
}
@PreDestroy
public void destroyMethod() throws Exception {
System.out.println("destroyMethod 被執(zhí)行");
}
}
第二種是:通過 在xml中定義init-method 和 destory-method方法
public class DataInitializer{
public void initMethod() throws Exception {
System.out.println("initMethod 被執(zhí)行");
}
public void destroyMethod() throws Exception {
System.out.println("destroyMethod 被執(zhí)行");
}
}
<bean id="dataInitializer" class="com.somnus.demo.DataInitializer" init-method="initMethod" destory-method="destroyMethod"/>
第三種是: 通過bean實(shí)現(xiàn)InitializingBean和 DisposableBean接口
import org.springframework.beans.factory.DisposableBean;
public class DataInitializer implements InitializingBean,DisposableBean{
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet 被執(zhí)行");
}
@Override
public void destroy() throws Exception {
System.out.println("destroy 被執(zhí)行");
}
}
其中第一種和第二種是同一種形式,只不過一種xml配置,另外一種采用注解形式罷了,有很大區(qū)別的是第三種,如果同一個(gè)bean同時(shí)采用兩種方式初始化的時(shí)候執(zhí)行某個(gè)方法,首先在執(zhí)行順序上就會(huì)體現(xiàn)出來。
先執(zhí)行afterPropertiesSet(),后執(zhí)行initMethod()
這里我們看下源碼
這方式在spring中是怎么實(shí)現(xiàn)的?
通過查看spring的加載bean的源碼類(AbstractAutowireCapableBeanFactory)可看出其中奧妙
AbstractAutowireCapableBeanFactory類中的invokeInitMethods講解的非常清楚,源碼如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
//判斷該bean是否實(shí)現(xiàn)了實(shí)現(xiàn)了InitializingBean接口,如果實(shí)現(xiàn)了InitializingBean接口,則只掉調(diào)用bean的afterPropertiesSet方法
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 {
//直接調(diào)用afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
return null;
}
},getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//直接調(diào)用afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
//判斷是否指定了init-method方法,如果指定了init-method方法,則再調(diào)用制定的init-method
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//進(jìn)一步查看該方法的源碼,可以發(fā)現(xiàn)init-method方法中指定的方法是通過反射實(shí)現(xiàn)
invokeCustomInitMethod(beanName, bean, mbd);
}
}
總結(jié):
1:spring為bean提供了兩種初始化bean的方式,實(shí)現(xiàn)InitializingBean接口,實(shí)現(xiàn)afterPropertiesSet方法,或者在配置文件中同過init-method指定,兩種方式可以同時(shí)使用
2:實(shí)現(xiàn)InitializingBean接口是直接調(diào)用afterPropertiesSet方法,比通過反射調(diào)用init-method指定的方法效率相對(duì)來說要高點(diǎn)。但是init-method方式消除了對(duì)spring的依賴
3:如果調(diào)用afterPropertiesSet方法時(shí)出錯(cuò),則不調(diào)用init-method指定的方法。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
在Spring中使用Knife4j進(jìn)行API文檔生成與管理的操作方法
Knife4j 是為Java MVC 框架(如Spring Boot、Spring MVC等)集成 Swagger 生成 API 文檔的增強(qiáng)解決方案,它基于 Swagger 的核心功能,通過定制化的前端界面和一些額外的特性,本文介紹了在Spring中使用Knife4j進(jìn)行API文檔生成與管理的操作方法,需要的朋友可以參考下2024-12-12
怎樣提高mybatis-plus中saveBatch方法的效率
這篇文章主要介紹了怎樣提高mybatis-plus中saveBatch方法的效率問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Spring Boot + Mybatis-Plus實(shí)現(xiàn)多數(shù)據(jù)源的方法
這篇文章主要介紹了Spring Boot + Mybatis-Plus實(shí)現(xiàn)多數(shù)據(jù)源的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
springboot @Valid注解對(duì)嵌套類型的校驗(yàn)功能
這篇文章主要介紹了springboot~@Valid注解對(duì)嵌套類型的校驗(yàn),主要介紹 @Valid在項(xiàng)目中的使用,需要的朋友可以參考下2018-05-05
SpringBoot項(xiàng)目中Druid自動(dòng)登錄功能實(shí)現(xiàn)
Druid是Java語言中最好的數(shù)據(jù)庫連接池,Druid能夠提供強(qiáng)大的監(jiān)控和擴(kuò)展功能,這篇文章主要介紹了SpringBoot項(xiàng)目中Druid自動(dòng)登錄功能實(shí)現(xiàn),需要的朋友可以參考下2024-08-08

