欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用spring容器在初始化Bean時(shí)前和后的操作

 更新時(shí)間:2021年09月24日 11:44:00   作者:Bwz_Learning  
這篇文章主要介紹了使用spring容器在初始化Bean時(shí)前和后的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

spring容器初始化Bean操作

在某些情況下,Spring容器在初始化Bean的時(shí)候,希望在初始化bean前和銷(xiāo)毀bean前進(jìn)行一些資源的加載和釋放的操作??梢酝ㄟ^(guò)一下三種方式完成。

  • Bean的方法加上@PostConstruct和@PreDestroy注解
  • 在xml中定義init-method和destory-method方法
  • Bean實(shí)現(xiàn)InitializingBean和DisposableBean接口

@PostConstruct和@PreDestroy注解

JavaBean代碼

@Component
public class PersonService {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @PostConstruct
    public void init() {
        System.out.println("PersonService.class init method ...");
    }
    @PreDestroy
    public void cleanUp() {
        System.out.println("PersonService.class cleanUp method ...");
    }
}

spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd        
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
    <!-- spring掃描的路徑 -->
    <context:component-scan base-package="spring.zhujie" />
</beans>

測(cè)試代碼和結(jié)果

測(cè)試代碼

public static void main(String[] args) {
     AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-zhujie.xml");
     context.registerShutdownHook();
}

運(yùn)行結(jié)果

PersonService.class init method ...

PersonService.class cleanUp method ...

在XML中定義init-method和destory-method方法

JavaBean代碼

public class PersonService {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public void init() {
        System.out.println("PersonService.class init method ...");
    }
    public void cleanUp() {
        System.out.println("PersonService.class cleanUp method ...");
    }
}

spring配置文件

<bean class="spring.zhujie.PersonService" init-method="init" destroy-method="cleanUp"/>

測(cè)試代碼和結(jié)果

測(cè)試代碼

public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-xml.xml");
        context.registerShutdownHook();
}

運(yùn)行結(jié)果

PersonService.class init method ...

六月 23, 2017 9:42:06 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose

信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@7a94c5e7: startup date [Fri Jun 23 21:42:06 CST 2017]; root of context hierarchy

PersonService.class cleanUp method ...

Bean實(shí)現(xiàn)InitializingBean和DisposableBean接口

JavaBean代碼

public class PersonService implements InitializingBean, DisposableBean {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("PersonService.class init method ...");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("PersonService.class cleanUp method ...");
    }
}

spring配置文件

<bean id="personService" class="spring.zhujie.PersonService" />

測(cè)試代碼和結(jié)果

測(cè)試代碼

public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-interface.xml");
        context.registerShutdownHook();
    }

運(yùn)行結(jié)果

PersonService.class init method ...

PersonService.class cleanUp method ...

Spring bean 初始化順序

InitializingBean, init-method 和 PostConstruct

1、概述

從接口的名字上不難發(fā)現(xiàn),InitializingBean 的作用就是在 bean 初始化后執(zhí)行定制化的操作。

Spring 容器中的 Bean 是有生命周期的,Spring 允許在 Bean 在初始化完成后以及 Bean 銷(xiāo)毀前執(zhí)行特定的操作,常用的設(shè)定方式有以下三種:

通過(guò)實(shí)現(xiàn) InitializingBean/DisposableBean 接口來(lái)定制初始化之后/銷(xiāo)毀之前的操作方法;

通過(guò) <bean> 元素的 init-method/destroy-method 屬性指定初始化之后 /銷(xiāo)毀之前調(diào)用的操作方法;

在指定方法上加上@PostConstruct 或@PreDestroy注解來(lái)制定該方法是在初始化之后還是銷(xiāo)毀之前調(diào)用。

2、InitializingBean vs init-method

接口定義如下:

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

接口只有一個(gè)方法afterPropertiesSet,

此方法的調(diào)用入口是負(fù)責(zé)加載 spring bean 的AbstractAutowireCapableBeanFactory,源碼如下:

protected void invokeInitMethods(String beanName, Object bean,
   RootBeanDefinition mbd) throws Throwable {
  boolean isInitializingBean = bean instanceof InitializingBean;
  if ((isInitializingBean)
    && (((mbd == null) || (!(mbd
      .isExternallyManagedInitMethod("afterPropertiesSet")))))) {
   if (this.logger.isDebugEnabled()) {
    this.logger
      .debug("Invoking afterPropertiesSet() on bean with name '"
        + beanName + "'");
   }
   //先調(diào)用afterPropertiesSet()進(jìn)行初始化
   if (System.getSecurityManager() != null) {
    try {
     AccessController.doPrivileged(
       new PrivilegedExceptionAction(bean) {
        public Object run() throws Exception {
         ((InitializingBean) this.val$bean)
           .afterPropertiesSet();
         return null;
        }
       }, getAccessControlContext());
    } catch (PrivilegedActionException pae) {
     throw pae.getException();
    }
   } else {
    ((InitializingBean) bean).afterPropertiesSet();
   }
  }
  
  //然后調(diào)用InitMethod()進(jìn)行初始化
  if (mbd != null) {
   String initMethodName = mbd.getInitMethodName();
   if ((initMethodName == null)
     || ((isInitializingBean) && ("afterPropertiesSet"
       .equals(initMethodName)))
     || (mbd.isExternallyManagedInitMethod(initMethodName)))
    return;
   invokeCustomInitMethod(beanName, bean, mbd);
  }
 }

從這段源碼可以得出以下結(jié)論:

spring為bean提供了兩種初始化bean的方式,實(shí)現(xiàn)InitializingBean接口,實(shí)現(xiàn)afterPropertiesSet方法,或者在配置文件中通過(guò)init-method指定,兩種方式可以同時(shí)使用

實(shí)現(xiàn)InitializingBean接口是直接調(diào)用afterPropertiesSet方法,比通過(guò)反射調(diào)用init-method指定的方法效率相對(duì)來(lái)說(shuō)要高點(diǎn)。但是init-method方式消除了對(duì)spring的依賴(lài)

先調(diào)用afterPropertiesSet,再執(zhí)行 init-method 方法,如果調(diào)用afterPropertiesSet方法時(shí)出錯(cuò),則不調(diào)用init-method指定的方法

3、@PostConstruct

通過(guò) debug 和調(diào)用棧找到類(lèi)InitDestroyAnnotationBeanPostProcessor, 其中的核心方法,即 @PostConstruct 方法調(diào)用的入口:

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
        try {
            metadata.invokeInitMethods(bean, beanName);
        }
        catch (InvocationTargetException ex) {
            throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
        }
        return bean;
    }

從命名上,我們就可以得到某些信息——這是一個(gè)BeanPostProcessor。BeanPostProcessor的postProcessBeforeInitialization是在Bean生命周期中afterPropertiesSet和init-method之前被調(diào)用的。另外通過(guò)跟蹤,@PostConstruct方法的調(diào)用方式也是通過(guò)反射機(jī)制。

4、小結(jié)一下吧

spring bean的初始化執(zhí)行順序:構(gòu)造方法 --> @PostConstruct注解的方法 --> afterPropertiesSet方法 --> init-method指定的方法。具體可以參考例子

afterPropertiesSet通過(guò)接口實(shí)現(xiàn)方式調(diào)用(效率上高一點(diǎn)),@PostConstruct和init-method都是通過(guò)反射機(jī)制調(diào)用

同理,bean銷(xiāo)毀過(guò)程的順序?yàn)椋篅PreDestroy > DisposableBean > destroy-method

不再展開(kāi),看源碼就好

測(cè)試代碼如下:

@Slf4j
public class InitSequenceBean implements InitializingBean {
    public InitSequenceBean() {
        log.info("InitSequenceBean: construct");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("InitSequenceBean: afterPropertiesSet");
    }
    @PostConstruct
    public void postConstruct() {
        log.info("InitSequenceBean: postConstruct");
    }
    public void initMethod() {
        log.info("InitSequenceBean: initMethod");
    }
}
@Configuration
public class SystemConfig {
    @Bean(initMethod = "initMethod", name = "initSequenceBean")
    public InitSequenceBean initSequenceBean() {
        return new InitSequenceBean();
    }
}
@Slf4j
public class InitSequenceBeanTest extends ApplicationTests {
    @Autowired
    private InitSequenceBean initSequenceBean;
    @Test
    public void initSequenceBeanTest() {
        log.info("Finish: {}", initSequenceBean.toString());
    }
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解spring boot jpa整合QueryDSL來(lái)簡(jiǎn)化復(fù)雜操作

    詳解spring boot jpa整合QueryDSL來(lái)簡(jiǎn)化復(fù)雜操作

    這篇文章主要介紹了詳解spring boot jpa整合QueryDSL來(lái)簡(jiǎn)化復(fù)雜操作,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • 說(shuō)說(shuō)字符串轉(zhuǎn) OffSetDateTime 你真的會(huì)用嗎

    說(shuō)說(shuō)字符串轉(zhuǎn) OffSetDateTime 你真的會(huì)用嗎

    這篇文章主要介紹了字符串轉(zhuǎn) OffSetDateTime 你真的會(huì)用嗎?具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java使用Collections.sort對(duì)中文進(jìn)行排序方式

    Java使用Collections.sort對(duì)中文進(jìn)行排序方式

    這篇文章主要介紹了Java使用Collections.sort對(duì)中文進(jìn)行排序方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 深入探索Java常量池

    深入探索Java常量池

    這篇文章主要介紹了深入探索Java常量池,涉及靜態(tài)常量池和運(yùn)行時(shí)常量池的介紹,常量池的好處,8種基本數(shù)據(jù)類(lèi)型的包裝類(lèi)和常量池等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 關(guān)于bigDecimal類(lèi)的精度保留方法

    關(guān)于bigDecimal類(lèi)的精度保留方法

    這篇文章主要介紹了關(guān)于bigDecimal類(lèi)的精度保留方法,計(jì)算機(jī)存儲(chǔ)的浮點(diǎn)數(shù)受存儲(chǔ)bit位數(shù)影響,只能保證一定范圍內(nèi)精準(zhǔn),超過(guò)bit范圍的只能取近似值,Java使用java.math.BigDecimal專(zhuān)門(mén)處理小數(shù)精度,需要的朋友可以參考下
    2023-07-07
  • 將Sublime Text 2配置為Java的IDE的教程

    將Sublime Text 2配置為Java的IDE的教程

    這篇文章主要介紹了將Sublime Text 2配置為Java的IDE的教程,包括能讓Sublime這個(gè)文本編輯器編譯和運(yùn)行Java程序等,需要的朋友可以參考下
    2015-07-07
  • MyBatis攔截器:給參數(shù)對(duì)象屬性賦值的實(shí)例

    MyBatis攔截器:給參數(shù)對(duì)象屬性賦值的實(shí)例

    下面小編就為大家?guī)?lái)一篇MyBatis攔截器:給參數(shù)對(duì)象屬性賦值的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • PowerJob的Evaluator方法工作流程源碼解讀

    PowerJob的Evaluator方法工作流程源碼解讀

    這篇文章主要介紹了PowerJob的Evaluator方法工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Java 基礎(chǔ)語(yǔ)法 異常處理

    Java 基礎(chǔ)語(yǔ)法 異常處理

    這篇我們就來(lái)介紹Java 基礎(chǔ)語(yǔ)法中長(zhǎng)遇到的那些異常及處理方法的一下相關(guān)資料,感興趣的小伙伴可以參考一下下面文章的詳細(xì)內(nèi)容,希望對(duì)你有所幫助
    2021-10-10
  • 使用java實(shí)現(xiàn)Xmodem協(xié)議

    使用java實(shí)現(xiàn)Xmodem協(xié)議

    這篇文章主要介紹了使用java實(shí)現(xiàn)Xmodem協(xié)議的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12

最新評(píng)論