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

使用Spring啟動(dòng)時(shí)運(yùn)行自定義業(yè)務(wù)

 更新時(shí)間:2021年07月22日 14:41:03   作者:夢(mèng)想畫(huà)家  
這篇文章主要介紹了使用Spring啟動(dòng)時(shí)運(yùn)行自定義業(yè)務(wù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

在Spring應(yīng)用啟動(dòng)時(shí)運(yùn)行自定義業(yè)務(wù)的場(chǎng)景很常見(jiàn),但應(yīng)用不當(dāng)也可能會(huì)導(dǎo)致一些問(wèn)題。

基于Spring控制反轉(zhuǎn)(Inverse of Control)功能用戶(hù)幾乎不用干預(yù)bean實(shí)例化過(guò)程,對(duì)于自定義業(yè)務(wù)則需要控制部分流程及容器,因此值得須特別關(guān)注。

1. Spring啟動(dòng)時(shí)運(yùn)行自定義業(yè)務(wù)

我們不能簡(jiǎn)單包括自定義業(yè)務(wù)在bean的構(gòu)造函數(shù)或在實(shí)例化任何對(duì)象之后調(diào)用方法,這些過(guò)程不由我們控制。請(qǐng)看示例:

@Component
public class InvalidInitExampleBean {
    @Autowired
    private Environment env;
    public InvalidInitExampleBean() {
        env.getActiveProfiles();
    }
}

這里嘗試在構(gòu)造函數(shù)中訪問(wèn)自動(dòng)裝配的屬性。當(dāng)調(diào)用構(gòu)造函數(shù)時(shí),Spring bean仍沒(méi)有全部初始化,因此導(dǎo)致NullPointerExceptions異常。下面介紹幾種方式解決此問(wèn)題。

1.1 @PostConstruct 注解

@PostConstruct注解用于方法上,實(shí)現(xiàn)bean初始化后立刻執(zhí)行一次。需要注意的是,即使沒(méi)有對(duì)象注入,Spring也會(huì)執(zhí)行注解方法。

@Component
public class PostConstructExampleBean {
    private static final Logger LOG 
      = Logger.getLogger(PostConstructExampleBean.class);
    @Autowired
    private Environment environment;
    @PostConstruct
    public void init() {
        LOG.info(Arrays.asList(environment.getDefaultProfiles()));
    }
}

上面示例可以實(shí)現(xiàn)Environment environment被安全注入,然后調(diào)用注解方法且不會(huì)出現(xiàn)空指針異常。

1.2 InitializingBean 接口

InitializingBean接口實(shí)現(xiàn)功能與上節(jié)類(lèi)似。但需要實(shí)現(xiàn)接口并重寫(xiě)afterPropertiesSet方法。

下面重寫(xiě)前節(jié)的示例:

@Component
public class InitializingBeanExampleBean implements InitializingBean {
    private static final Logger LOG 
      = Logger.getLogger(InitializingBeanExampleBean.class);
    @Autowired
    private Environment environment;
    @Override
    public void afterPropertiesSet() throws Exception {
        LOG.info(Arrays.asList(environment.getDefaultProfiles()));
    }
}

1.3 ApplicationListener 監(jiān)聽(tīng)器

該方法可用于在Spring上下文初始化之后執(zhí)行自定義業(yè)務(wù)。因此不針對(duì)特定bean,而是等待所有bean初始化之后。應(yīng)用時(shí)需要實(shí)現(xiàn)ApplicationListener接口:

@Component
public class StartupApplicationListenerExample implements 
  ApplicationListener<ContextRefreshedEvent> {
    private static final Logger LOG 
      = Logger.getLogger(StartupApplicationListenerExample.class);
    public static int counter;
    @Override public void onApplicationEvent(ContextRefreshedEvent event) {
        LOG.info("Increment counter");
        counter++;
    }
}

同樣可以引入@EventListener注解實(shí)現(xiàn):

@Component
public class EventListenerExampleBean {
    private static final Logger LOG 
      = Logger.getLogger(EventListenerExampleBean.class);
    public static int counter;
    @EventListener
    public void onApplicationEvent(ContextRefreshedEvent event) {
        LOG.info("Increment counter");
        counter++;
    }
}

上面示例使用ContextRefreshedEvent,具體選擇哪種事件根據(jù)你的業(yè)務(wù)需要。

1.4 @Bean的初始化方法

該注解的initMethod屬性可用于在bean初始化之后執(zhí)行方法,示例:

public class InitMethodExampleBean {
    private static final Logger LOG = Logger.getLogger(InitMethodExampleBean.class);
    @Autowired
    private Environment environment;
    public void init() {
        LOG.info(Arrays.asList(environment.getDefaultProfiles()));
    }
}

既不要實(shí)現(xiàn)接口,也不要特定注解。通過(guò)注解定義Bean:

@Bean(initMethod="init")
public InitMethodExampleBean initMethodExampleBean() {
    return new InitMethodExampleBean();
}

對(duì)應(yīng)xml配置:

<bean id="initMethodExampleBean"
  class="com.baeldung.startup.InitMethodExampleBean"
  init-method="init">
</bean>

1.5 構(gòu)造函數(shù)注入

如果使用構(gòu)造器注入屬性,可以簡(jiǎn)單地在構(gòu)造函數(shù)中包括業(yè)務(wù):

@Component 
public class LogicInConstructorExampleBean {
    private static final Logger LOG 
      = Logger.getLogger(LogicInConstructorExampleBean.class);
    private final Environment environment;
    @Autowired
    public LogicInConstructorExampleBean(Environment environment) {
        this.environment = environment;
        LOG.info(Arrays.asList(environment.getDefaultProfiles()));
    }
}

1.6 Spring Boot CommandLineRunner接口

Spring Boot 提供了CommandLineRunner接口,重寫(xiě)run方法,可以在應(yīng)用啟動(dòng)時(shí)Spring應(yīng)用上下文實(shí)例化之后調(diào)用。

@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
    private static final Logger LOG =
      LoggerFactory.getLogger(CommandLineAppStartupRunner.class);
    public static int counter;
    @Override
    public void run(String...args) throws Exception {
        LOG.info("Increment counter");
        counter++;
    }
}

CommandLineRunner bean在相同上下文中可以定義多個(gè),通過(guò)使用Ordered 接口或@Ordere注解確定順序。

1.7 Spring Boot ApplicationRunner

與CommandLineRunner類(lèi)似,Spring Boot 也提供了ApplicationRunner接口,重寫(xiě)run方法可以實(shí)現(xiàn)應(yīng)用啟動(dòng)時(shí)執(zhí)行自定義業(yè)務(wù)。另外其回調(diào)方法沒(méi)有使用String參數(shù),而是使用ApplicationArguments類(lèi)的實(shí)例。

ApplicationArguments有方法可以獲取可選參數(shù)及普通參數(shù)的值,參數(shù)前有–的表示可選參數(shù)。

@Component
public class AppStartupRunner implements ApplicationRunner {
    private static final Logger LOG =
      LoggerFactory.getLogger(AppStartupRunner.class);
    public static int counter;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        LOG.info("Application started with option names : {}", 
          args.getOptionNames());
        LOG.info("Increment counter");
        counter++;
    }
}

2. 執(zhí)行順序

多種方法對(duì)bean同時(shí)進(jìn)行控制,對(duì)應(yīng)執(zhí)行順序如下:

  1. 構(gòu)造函數(shù)
  2. @PostConstruct注解方法
  3. InitializingBean的afterPropertiesSet()
  4. @Bean或xml中標(biāo)注的初始化方法

讀者可以自行測(cè)試進(jìn)行驗(yàn)證。

3. 總結(jié)

本文介紹多種方式實(shí)現(xiàn)在Spring啟動(dòng)時(shí)實(shí)現(xiàn)自定義業(yè)務(wù)。通過(guò)對(duì)比不同方式實(shí)現(xiàn)加深對(duì)Spring的理解,掌握更多控制bean實(shí)例化過(guò)程的方式。以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java遞歸算法的實(shí)例詳解

    java遞歸算法的實(shí)例詳解

    在本篇文章里小編給大家整理了關(guān)于java遞歸算法的實(shí)例內(nèi)容,以及相關(guān)知識(shí)點(diǎn)總結(jié),需要的朋友們可以學(xué)習(xí)下。
    2020-02-02
  • Java Runtime類(lèi)詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java Runtime類(lèi)詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Runtime類(lèi)封裝了運(yùn)行時(shí)的環(huán)境。每個(gè) Java 應(yīng)用程序都有一個(gè) Runtime 類(lèi)實(shí)例,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境相連接。下面通過(guò)本文給大家分享Java Runtime類(lèi)詳解,需要的朋友參考下吧
    2017-04-04
  • Java多線(xiàn)程 線(xiàn)程狀態(tài)原理詳解

    Java多線(xiàn)程 線(xiàn)程狀態(tài)原理詳解

    這篇文章主要介紹了Java多線(xiàn)程 線(xiàn)程狀態(tài)原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Thymeleaf渲染網(wǎng)頁(yè)時(shí)中文亂碼的問(wèn)題及解決

    Thymeleaf渲染網(wǎng)頁(yè)時(shí)中文亂碼的問(wèn)題及解決

    這篇文章主要介紹了Thymeleaf渲染網(wǎng)頁(yè)時(shí)中文亂碼的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 在SpringBoot中配置日志級(jí)別和輸出格式的教程詳解

    在SpringBoot中配置日志級(jí)別和輸出格式的教程詳解

    在開(kāi)發(fā)一個(gè)應(yīng)用程序時(shí),日志記錄是非常重要的一環(huán),SpringBoot提供了多種日志輸出方式和配置選項(xiàng),本文將介紹如何在SpringBoot應(yīng)用程序中配置日志級(jí)別和輸出格式,需要的朋友可以參考下
    2023-06-06
  • Spring Boot緩存實(shí)戰(zhàn) Caffeine示例

    Spring Boot緩存實(shí)戰(zhàn) Caffeine示例

    本篇文章主要介紹了Spring Boot緩存實(shí)戰(zhàn) Caffeine示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • Java中一些常見(jiàn)的并發(fā)集合類(lèi)的使用

    Java中一些常見(jiàn)的并發(fā)集合類(lèi)的使用

    并發(fā)集合是一種特殊的數(shù)據(jù)結(jié)構(gòu),它允許多個(gè)線(xiàn)程安全地訪問(wèn)和修改,本文主要介紹了Java中一些常見(jiàn)的并發(fā)集合類(lèi)的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • 解讀Spring-boot的debug調(diào)試

    解讀Spring-boot的debug調(diào)試

    這篇文章主要介紹了解讀Spring-boot的debug調(diào)試,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 一文帶你深入了解Java?TreeMap

    一文帶你深入了解Java?TreeMap

    TreeMap是Map家族中的一員,也是用來(lái)存放key-value鍵值對(duì)的。平時(shí)在工作中使用的可能并不多。本文將基于jdk8對(duì)其做一個(gè)講解,感興趣的可以了解一下
    2022-09-09
  • 如何使用IntelliJ IDEA的HTTP Client進(jìn)行接口驗(yàn)證

    如何使用IntelliJ IDEA的HTTP Client進(jìn)行接口驗(yàn)證

    這篇文章主要介紹了如何使用IntelliJ IDEA的HTTP Client進(jìn)行接口驗(yàn)證,本文給大家分享最新完美解決方案,感興趣的朋友跟隨小編一起看看吧
    2024-06-06

最新評(píng)論