日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Spring中bean的初始化和銷毀幾種實(shí)現(xiàn)方式詳解

瀏覽:115日期:2023-08-03 17:45:50

Bean的生命周期 : 創(chuàng)建bean對(duì)象 ? 屬性賦值 ? 初始化方法調(diào)用前的操作 ? 初始化方法 ? 初始化方法調(diào)用后的操作 ? …-- 銷毀前操作 ? 銷毀方法的調(diào)用。

【1】init-method和destroy-method

自定義初始化方法和銷毀方法兩種方式:xml配置和注解。

① xml配置

<bean scope='singleton' init-method='init' destroy-method='cleanUp' autowire='byName' lazy-init='true' > </bean>

② 注解配置

@Scope('singleton') @Lazy @Bean(name='person',initMethod='init',destroyMethod='cleanUp', autowire=Autowire.BY_NAME) public Person person01(){ return new Person('lisi', 20); }

單實(shí)例bean在容器創(chuàng)建完成前會(huì)進(jìn)行創(chuàng)建并初始化,在容器銷毀的時(shí)候進(jìn)行銷毀。多實(shí)例bean(scope=prototype)在第一次獲取該bean實(shí)例時(shí)才會(huì)創(chuàng)建并初始化,且容器不負(fù)責(zé)該bean的銷毀。

【2】InitializingBean 和DisposableBean

InitializingBean 接口:

public interface InitializingBean {void afterPropertiesSet() throws Exception;}

在BeanFactory設(shè)置完bean屬性后執(zhí)行

需要被bean實(shí)現(xiàn)的接口,一旦bean的屬性被BeanFactory設(shè)置后需要做出反應(yīng): 如,執(zhí)行自定義初始化,或者僅僅是檢查是否設(shè)置了所有強(qiáng)制屬性。

實(shí)現(xiàn)InitializingBean 的可替代方式為給bean指定一個(gè)自定義的init-method,例如在一個(gè)xml bean 定義中。

在bean的屬性設(shè)置之后進(jìn)行操作,不返回任何值但是允許拋出異常。

DisposableBean接口:

public interface DisposableBean {void destroy() throws Exception;}

被bean實(shí)現(xiàn)的接口,在銷毀時(shí)釋放資源,在Bean銷毀的時(shí)候調(diào)用該方法。

如果銷毀一個(gè)緩存的單例,一個(gè)BeanFactory 可能會(huì)調(diào)用這個(gè)銷毀方法。

在容器關(guān)閉時(shí),應(yīng)用上下文會(huì)銷毀所有的單例bean。

一種替代實(shí)現(xiàn)DisposableBean 接口的方案為指定一個(gè)自定義的destroy-method方法,例如在一個(gè)xml bean定義中。

自定義bean實(shí)現(xiàn)上述兩個(gè)接口

@Componentpublic class Cat implements InitializingBean,DisposableBean {public Cat(){System.out.println('cat constructor...');}@Overridepublic void destroy() throws Exception {// TODO Auto-generated method stubSystem.out.println('cat...destroy...');}@Overridepublic void afterPropertiesSet() throws Exception {// TODO Auto-generated method stubSystem.out.println('cat...afterPropertiesSet...');}}

測(cè)試結(jié)果

cat constructor...cat...afterPropertiesSet...容器創(chuàng)建完成...四月 08, 2018 6:35:46 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@11028347: startup date [Sun Apr 08 18:35:46 CST 2018]; root of context hierarchycat...destroy...

【3】@PostConstruct和@PreDestroy

使用JSR250規(guī)范定義的兩個(gè)注解:

@PostConstruct: PostConstruct注解作用在方法上,在依賴注入完成后進(jìn)行一些初始化操作。這個(gè)方法在類被放入service之前被調(diào)用,所有支持依賴項(xiàng)注入的類都必須支持此注解。

@PreDestroy:在容器銷毀bean之前通知我們進(jìn)行清理工作

自定義類使用上述兩個(gè)注解

@Componentpublic class Dog implements ApplicationContextAware {//@Autowiredprivate ApplicationContext applicationContext;public Dog(){System.out.println('dog constructor...');}//對(duì)象創(chuàng)建并賦值之后調(diào)用@PostConstructpublic void init(){System.out.println('Dog....@PostConstruct...');}//容器移除對(duì)象之前@PreDestroypublic void detory(){System.out.println('Dog....@PreDestroy...');}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// TODO Auto-generated method stubthis.applicationContext = applicationContext;}}

測(cè)試結(jié)果如下

dog constructor...Dog....@PostConstruct...容器創(chuàng)建完成...四月 08, 2018 6:42:11 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@11028347: startup date [Sun Apr 08 18:42:10 CST 2018]; root of context hierarchyDog....@PreDestroy...

【4】BeanPostProcessor-Bean后置處理器

① 什么是bean后置處理器

在bean初始化前后進(jìn)行一些處理工作

postProcessBeforeInitialization:在初始化之前工作 postProcessAfterInitialization:在初始化之后工作

其接口源碼如下:

public interface BeanPostProcessor {Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}

自定義MyBeanPostProcessor實(shí)現(xiàn)該接口:

/** * 后置處理器:初始化前后進(jìn)行處理工作 * 將后置處理器加入到容器中 * @author lfy */@Componentpublic class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println('BeanPostProcessor.postProcessBeforeInitialization...'+beanName+'=>'+bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// TODO Auto-generated method stubSystem.out.println('BeanPostProcessor.postProcessAfterInitialization...'+beanName+'=>'+bean);return bean;}}

② BeanPostProcessor原理

AbstractAutowireCapableBeanFactory中關(guān)于bean和BeanPostProcessor執(zhí)行次序由上到下

//給bean進(jìn)行屬性賦值populateBean(beanName, mbd, instanceWrapper);//然后調(diào)用initializeBean方法Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd){applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);//執(zhí)行自定義初始化invokeInitMethods(beanName, wrappedBean, mbd);applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}

AbstractAutowireCapableBeanFactory.initializeBean源碼如下:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {invokeAwareMethods(beanName, bean);return null;}}, getAccessControlContext());}else {//調(diào)用意識(shí)/通知方法invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {//調(diào)用bean后置處理器的前置方法wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}//調(diào)用初始化方法try {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()) {////調(diào)用bean后置處理器的后置方法wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}

AbstractAutowireCapableBeanFactory.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 + '’');}//調(diào)用InitializingBean.afterPropertiesSetif (System.getSecurityManager() != null) {try {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {@Overridepublic Object run() throws Exception {((InitializingBean) bean).afterPropertiesSet();return null;}}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {((InitializingBean) bean).afterPropertiesSet();}}//調(diào)用自定義初始化方法if (mbd != null) {String initMethodName = mbd.getInitMethodName();if (initMethodName != null && !(isInitializingBean && 'afterPropertiesSet'.equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);}}}

【5】Spring底層使用BeanPostProcessor

Spring框架底層存在大量BeanPostProcessor,如下圖:

Spring中bean的初始化和銷毀幾種實(shí)現(xiàn)方式詳解

示例一 :BeanValidationPostProcessor是處理bean校驗(yàn)

其Javadoc如下:

/** * Simple {@link BeanPostProcessor} that checks JSR-303 constraint annotations * in Spring-managed beans, throwing an initialization exception in case of * constraint violations right before calling the bean’s init method (if any). * * @author Juergen Hoeller * @since 3.0 */public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean {private Validator validator;private boolean afterInitialization = false;//...}

示例二:ApplicationContextAwareProcessor幫助獲取容器上下文

其Javadoc如下:

/** * {@link org.springframework.beans.factory.config.BeanPostProcessor} * implementation that passes the ApplicationContext to beans that * implement the {@link EnvironmentAware}, {@link EmbeddedValueResolverAware}, * {@link ResourceLoaderAware}, {@link ApplicationEventPublisherAware}, * {@link MessageSourceAware} and/or {@link ApplicationContextAware} interfaces. * * <p>Implemented interfaces are satisfied in order of their mention above. * * <p>Application contexts will automatically register this with their * underlying bean factory. Applications do not use this directly. * * @author Juergen Hoeller * @author Costin Leau * @author Chris Beams * @since 10.10.2003 * @see org.springframework.context.EnvironmentAware * @see org.springframework.context.EmbeddedValueResolverAware * @see org.springframework.context.ResourceLoaderAware * @see org.springframework.context.ApplicationEventPublisherAware * @see org.springframework.context.MessageSourceAware * @see org.springframework.context.ApplicationContextAware * @see org.springframework.context.support.AbstractApplicationContext#refresh() */class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ConfigurableApplicationContext applicationContext;private final StringValueResolver embeddedValueResolver;//...}

如【3】中的dog類為例,其debug示意圖如下:

Spring中bean的初始化和銷毀幾種實(shí)現(xiàn)方式詳解

【6】初始化和銷毀方式測(cè)試

① 如果一個(gè)bean 綜合應(yīng)用下面六種種方式,執(zhí)行順序會(huì)怎樣呢

Bean類如下:

public class Person implements InitializingBean,DisposableBean { private String name; private Integer age=1; public Person(String name, Integer age) { this.name = name; this.age = age; System.out.println('Person(String name, Integer age) constructor'+this); } public Person() { super(); System.out.println('Person() constructor'+age); } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return 'Person{' +'name=’' + name + ’’’ +', age=' + age +’}’; }// 自定義init方法 public void init(){ System.out.println('-----Person.init()-----'+this); } // 自定義銷毀方法 public void cleanUp(){ System.out.println('-----Person.cleanUp()-----'+this); }// InitializingBean的實(shí)現(xiàn)方法 @Override public void afterPropertiesSet() throws Exception { System.out.println('-----InitializingBean.afterPropertiesSet()-----'+this); }//DisposableBean 的實(shí)現(xiàn)方法 @Override public void destroy() throws Exception { System.out.println('-----DisposableBean.destroy()-----'+this); } //對(duì)象創(chuàng)建并賦值之后調(diào)用 @PostConstruct public void init2(){ System.out.println('-----@PostConstruct-----'+this); } //容器移除對(duì)象之前 @PreDestroy public void destory2(){ System.out.println('-----@PreDestroy-----'+this); }}

配置類如下:

public class Person implements InitializingBean,DisposableBean { private String name; private Integer age=1; public Person(String name, Integer age) { this.name = name; this.age = age; System.out.println('Person(String name, Integer age) constructor'+this); } public Person() { super(); System.out.println('Person() constructor'+age); } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return 'Person{' +'name=’' + name + ’’’ +', age=' + age +’}’; }// 自定義init方法 public void init(){ System.out.println('-----Person.init()-----'+this); } // 自定義銷毀方法 public void cleanUp(){ System.out.println('-----Person.cleanUp()-----'+this); }// InitializingBean的實(shí)現(xiàn)方法 @Override public void afterPropertiesSet() throws Exception { System.out.println('-----InitializingBean.afterPropertiesSet()-----'+this); }//DisposableBean 的實(shí)現(xiàn)方法 @Override public void destroy() throws Exception { System.out.println('-----DisposableBean.destroy()-----'+this); } //對(duì)象創(chuàng)建并賦值之后調(diào)用 @PostConstruct public void init2(){ System.out.println('-----@PostConstruct-----'+this); } //容器移除對(duì)象之前 @PreDestroy public void destory2(){ System.out.println('-----@PreDestroy-----'+this); }}

測(cè)試結(jié)果如下:

// 創(chuàng)建并初始化Person(String name, Integer age) constructorPerson{name=’lisi’, age=20}-----@PostConstruct-----Person{name=’lisi’, age=20}-----InitializingBean.afterPropertiesSet()-----Person{name=’lisi’, age=20}-----Person.init()-----Person{name=’lisi’, age=20}//容器將要銷毀-----@PreDestroy-----Person{name=’lisi’, age=20}-----DisposableBean.destroy()-----Person{name=’lisi’, age=20}-----Person.cleanUp()-----Person{name=’lisi’, age=20}

即,最先使用bean的構(gòu)造器為bean屬性賦值,接著JSR250規(guī)范定義的兩個(gè)注解,其次是InitializingBean和DisposableBean接口,最后才是我們自定義的初始化方法和銷毀方法。注意,這里還沒有引入BeanPostProcessor。

② 在①的基礎(chǔ)上添加BeanPostProcessor

實(shí)例化bean并進(jìn)行初始化

//調(diào)用構(gòu)造方法Person(String name, Integer age) constructorPerson{name=’lisi’, age=20}//bean初始化前BeanPostProcessor.postProcessBeforeInitialization...person=>Person{name=’lisi’, age=20}//初始化操作-----@PostConstruct-----Person{name=’lisi’, age=20}-----InitializingBean.afterPropertiesSet()-----Person{name=’lisi’, age=20}-----Person.init()-----Person{name=’lisi’, age=20}//bean初始化后操作BeanPostProcessor.postProcessAfterInitialization...person=>Person{name=’lisi’, age=20}

過程如下:類構(gòu)造函數(shù)-->BeanPostProcessor-->@PostConstruct-->InitializingBean-->init()-->BeanPostProcessor

銷毀bean

-----@PreDestroy-----Person{name=’lisi’, age=20}-----DisposableBean.destroy()-----Person{name=’lisi’, age=20}-----Person.cleanUp()-----Person{name=’lisi’, age=20}

完整圖示如下(同顏色的說明相對(duì)應(yīng)):

Spring中bean的初始化和銷毀幾種實(shí)現(xiàn)方式詳解

在調(diào)用bean的構(gòu)造函數(shù)時(shí)會(huì)根據(jù)入?yún)閎ean屬性賦值,如果入?yún)榭談t會(huì)給bean屬性賦予默認(rèn)值,引用類型為null,基本類型比如int為0。

【7】 @Autowired注解的值何時(shí)放入?

如下所示,redisTemplate這個(gè)依賴何時(shí)被容器注入到RedisController中?

Spring中bean的初始化和銷毀幾種實(shí)現(xiàn)方式詳解

通過上面分析可知,依賴注入是在@PostConstruct注解的方法調(diào)用前被完成的(在populateBean()方法中被注入):

Spring中bean的初始化和銷毀幾種實(shí)現(xiàn)方式詳解

那么具體什么時(shí)候哪個(gè)類完成的 @Autowired注解注入依賴呢?

在類被實(shí)例化后由BeanPostProcessor完成的,哪個(gè)BeanPostProcessor?

具體是由AutowiredAnnotationBeanPostProcessor 完成的:

Spring中bean的初始化和銷毀幾種實(shí)現(xiàn)方式詳解

到此這篇關(guān)于Spring中bean的初始化和銷毀幾種實(shí)現(xiàn)方式詳解的文章就介紹到這了,更多相關(guān)Spring中bean初始化和銷毀內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本中文字幕一区二区| 欧美欧美黄在线二区| 精品久久久久中文字幕小说| 亚洲色图国产| 喷白浆一区二区| 日韩大片在线播放| 国产福利一区二区三区在线播放| 亚洲欧美高清| 欧美专区18| 日韩免费小视频| 欧美激情久久久久久久久久久| 欧美视频一区| 国产日韩欧美一区在线| 欧美永久精品| 国产精品香蕉| 精品欧美日韩精品| 欧美激情另类| 伊伊综合在线| 今天的高清视频免费播放成人| 香蕉国产精品| 中国女人久久久| 欧美在线综合| 日韩av一二三| 欧美激情综合| 国产香蕉精品| 精品三级在线观看视频| 日韩一区亚洲二区| 在线视频观看日韩| 欧美亚洲国产精品久久| 亚洲色图网站| 欧美男人天堂| 亚洲性色av| 国产综合精品| 国产精品试看| 日产午夜精品一线二线三线| 亚洲免费观看| 国产精品久久久久久av公交车| 国产精品欧美在线观看| 免费在线欧美黄色| 国产精品久久久久9999高清| 福利精品在线| 丝瓜av网站精品一区二区| 亚洲精品进入| 欧美好骚综合网| 欧美日韩一区二区三区四区在线观看| 国产欧美一区二区三区精品酒店| 欧美日韩中出| 日韩精品一级二级| 欧美色图国产精品| 老司机免费视频一区二区| 亚洲一区欧美| 天堂8中文在线最新版在线| 蜜桃久久精品一区二区| 精品在线播放| 狠狠久久伊人| 奇米亚洲欧美| 久久久久久久久丰满| 日韩成人精品一区| 在线精品福利| 亚洲手机在线| 欧美日韩精品一本二本三本| 亚洲v天堂v手机在线| 韩日一区二区| 丝袜美腿一区二区三区| 久久av影院| 好吊一区二区三区| 欧美欧美黄在线二区| 黄色在线观看www| 福利一区视频| 综合干狼人综合首页| 亚洲精品人人| 日本精品另类| 亚洲精品影院在线观看| 日本在线成人| 日韩av中文字幕一区| 麻豆一区二区在线| 精品久久一区| 日韩中文欧美在线| 久久中文字幕导航| 国产激情久久| 亚洲免费影院| 欧美韩日一区| 国产亚洲一区| 国产精品呻吟| 国产精品欧美大片| 亚洲欧美日韩视频二区| 久久久久久一区二区| 欧美视频二区| 亚洲免费婷婷| 亚洲电影有码| 国产精品xxx| 丝袜诱惑制服诱惑色一区在线观看| 国产精品不卡| 国产欧美大片| 日韩精品一二三| 日韩一区二区三区免费| 国产视频一区二| 日韩不卡在线观看日韩不卡视频| 久久精品理论片| 欧美国产另类| 国产精品天堂蜜av在线播放| 久久久久久久久丰满| 久久高清一区| 精品国产美女a久久9999| 2023国产精品久久久精品双| 欧美日韩一区二区三区在线电影| 日韩一区二区三区在线免费观看| 99视频精品免费观看| 高清av一区| 国产精品九九| 不卡在线一区| 欧美成人精品午夜一区二区| 蜜臀av国产精品久久久久| 国产精品久久久久久久久久妞妞| 不卡专区在线| 一区视频在线| 欧美一区久久久| 青青国产精品| 久久亚洲精品伦理| 99久久99久久精品国产片果冰 | 国产麻豆精品| 亚洲专区一区| 久久不卡日韩美女| 蜜桃免费网站一区二区三区| 亚洲人www| 日韩一区二区三免费高清在线观看 | 日韩av免费| 亚洲精品在线二区| 亚洲精品国产偷自在线观看| 国产一区二区三区成人欧美日韩在线观看| 亚洲日本免费电影| 免费欧美一区| 久久天堂av| 国产+成+人+亚洲欧洲在线| 日韩欧乱色一区二区三区在线| 亚洲午夜电影| 久久在线91| 免费一区二区视频| 最新亚洲一区| 精品视频99| 日韩欧美三级| 成人黄色av| 久久一区精品| 中文av在线全新| 麻豆国产精品| 欧美日韩调教| 91精品丝袜国产高跟在线| 午夜精品影院| 午夜欧美精品| 波多野结衣一区| 国产专区一区| 激情综合激情| 欧美日韩在线网站| 欧美日韩视频免费观看| 91成人在线| 国产欧美午夜| 一本一道久久a久久精品蜜桃| 久久精品国内一区二区三区水蜜桃| 亚洲国产福利| 偷拍精品精品一区二区三区| 日本韩国欧美超级黄在线观看| 日韩不卡在线| 免费av一区二区三区四区| 亚洲一级少妇| 亚洲精品国产偷自在线观看| 国产视频亚洲| 亚洲狼人精品一区二区三区| 综合色一区二区| 国产亚洲一卡2卡3卡4卡新区| 成人精品高清在线视频| 日韩国产欧美一区二区| av中文资源在线资源免费观看| 一本色道精品久久一区二区三区| 日韩国产欧美| 日本精品另类| 亚洲手机视频| 久久69成人| 国产日韩欧美一区二区三区| 欧美精品黄色| 免费不卡在线视频| 好吊日精品视频| 亚洲专区视频| 青草国产精品| 欧美日韩国产一区精品一区| 日韩一区精品视频| 久久精品伊人| 亚洲久久视频| 亚洲精品一二三区区别| 国产精品亚洲产品| 蜜臀va亚洲va欧美va天堂| 久久久91麻豆精品国产一区| 日韩激情av在线| 男女男精品网站| 色天使综合视频| 五月天久久久| 日本亚洲最大的色成网站www | 国产日韩视频在线| 欧美激情国产在线| 欧美性www| 国产精品久久久免费|