<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近在做一個專案啟動時載入設定到SpringBoot容器中的功能,看到了Spring中有很多在容器初始化時的介面,這些介面或註解包括InitializingBean、@PostConstruct、SmartInitializingSingleton、BeanPostProcess
等等,這麼多都可以在初始化時使用,但是他們有什麼區別呢,下面就來說說他們之間的區別
@PostConstruct
這個註解在實際的開發中有較多的用到
@Component public class TestP { @PostConstruct public void test() { System.out.println("@PostConstruct"); }
這樣在容器啟動過程中就回執行列印,看起來他像是物件的構造方法,其實他的作用是,當一個物件A中存在@Autowire修飾的依賴B時,正常來說,物件會先執行自己的構造方法,然後再去注入依賴,但是我們現在有一種情況,在物件範例化時,要執行構造方法,但是構造方法中用到依賴B,這個時候用 @PostConstruct就能解決這個問題。
public class TestP implements InitializingBean, SmartInitializingSingleton { @Autowired Context context; ``` public TestP () { System.out.println(context); } ``` @PostConstruct public void test() { System.out.println(context); System.out.println("@PostConstruct"); }
輸出
null
com.example.demo1.bean.Context@4f96a58
@PostConstruct
InitializingBean
他提供bean初始化的回撥處理功能,看下這個介面的原始碼
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); //判斷該bean是否實現了實現了InitializingBean介面,如果實現了InitializingBean介面,則只掉呼叫bean的afterPropertiesSet方法 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 { //直接呼叫afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); return null; } },getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //直接呼叫afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null) { String initMethodName = mbd.getInitMethodName(); //判斷是否指定了init-method方法,如果指定了init-method方法,則再呼叫制定的init-method if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { //進一步檢視該方法的原始碼,可以發現init-method方法中指定的方法是通過反射實現 invokeCustomInitMethod(beanName, bean, mbd); } }
可以看到,只要實現了這個介面的bean都會執行裡面的afterPropertiesSet
方法,那他和 @PostConstruct
有什麼區別呢,區別是他們的生命週期排序不同,@PostConstruct
是對單個Bean範例化時使用,而InitializingBean
是在所有spring bean範例化後對bean進行處理,⼤致的步驟是這樣的
範例化bean,這⾥會調⽤構造⽅法
填充屬性,就是依賴注⼊
初始化bean,
BeanPostProcess
這個介面主要是對註冊的bean中的屬性進行初始化時的修改
@Component public class BeanPostTest implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("執行1--------------- - " + bean.getClass().getName() + " - " + beanName); return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("執行2--------------- - " + bean.getClass().getName() + " - " + beanName); return null; } }
他和InitializingBean
區別一個是執行順序不同
他有兩個方法分別在在InitializingBean
執行前執行後執行,第二個區別就是InitializingBean
是一個可以進一步調整bean的範例的介面,不過並不是每個類都會來執行這個介面方法,這個介面只針對當前實現類,而BeanPostProcess是針對所有bean的,每一個bean被註冊,都會被執行一次這兩個方法
SmartInitializingSingleton
這個是在spring 4.1版本才推出的介面,他的執行時時機是在單例預範例化階段結束時呼叫,並保證已經建立了所有常規單例bean,所以他的執行順序是比較靠後的,考慮到一些bean的註冊及修改使用SmartInitializingSingleton
是比較穩妥的一種方式
``` @Component public class GetuiAccountConfigInit implements SmartInitializingSingleton { @Override public void afterSingletonsInstantiated() { } } ```
Commandlinerunner 這個介面是springBoot的介面,他是在所有bean都載入後才會執行的,如果實現這個介面,可以很好的在啟動時初始化資源,因為所有的bean都可以使用了
@Component public class Runner implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("執行初始化"); } }
如果我們要執行的程式有順序要求,還可以使用@Order註解
@Component @Order(1) public class OrderRunner1 implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("The OrderRunner1 start to initialize ..."); } } @Component @Order(2) public class OrderRunner1 implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("The OrderRunner2 start to initialize ..."); } }
Spring由於設計上比較靈活所以留了很多介面,讓開發人員進行拓展,這本身是一個很好的學習借鑑的經驗,現在大部分的開發使用的都是spring的框架,這就要求我們做一些設計時要了解框架的特性,才能進行更好的設計,上面的幾個介面是相對來說比較常用的介面,裡面的技術細節也值得推敲,希望對大家有所幫助。
到此這篇關於詳細SpringBoot生命週期介面的使用的文章就介紹到這了,更多相關SpringBoot生命週期介面內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45