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

SpringBoot中Aware接口使用及原理解析

 更新時間:2023年08月28日 10:14:47   作者:LBruse  
在Spring中存在一個Aware接口,實現(xiàn)該接口可以讓我們的Bean獲取到Spring容器中特定的資源,但該接口只是個標(biāo)記接口,不存在任何方法,本文將給大家詳細(xì)介紹一下SpringBoot中Aware接口使用及原理,需要的朋友可以參考下

Aware接口

Spring中存在一個Aware接口,實現(xiàn)該接口可以讓我們的Bean獲取到Spring容器中特定的資源,但該接口只是個標(biāo)記接口,不存在任何方法,因此我們還需要繼承Aware來做特定資源獲取的實現(xiàn)。

Spring中有不少繼承于Aware的接口的實現(xiàn),比如當(dāng)前Bean想要獲取環(huán)境變量時,可以實現(xiàn)EnvironmentAware接口,想要獲取應(yīng)用上下文則可以實現(xiàn)ApplicationContextAware接口。

常用的Aware實現(xiàn)

接口作用
BeanClassLoaderAware獲得類加載器
BeanNameAware獲取容器中Bean名稱
BeanFactoryAware獲取bean創(chuàng)建工廠
EnvironmentAware獲得環(huán)境變量
ResourceLoaderAware獲取資源加載器
ApplicationEventPublisherAware獲取應(yīng)用事件發(fā)布器
MessageSourceAware獲取文本信息
ApplicationContextAware獲取當(dāng)前應(yīng)用上下文

Aware示例

以下做一個代碼示例,實現(xiàn)EnvironmentAware接口,獲取到Environment并嘗試獲取并輸出自定義的屬性。除了Aware外,還涉及到之前提到的CommandLineRunner 和Property,可以點擊回顧。

創(chuàng)建一個AwareCommandLineRunner,實現(xiàn)EnvironmentAware接口,并嘗試獲取并輸出redis-host屬性

package geek.springboot.application.runner;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class AwareCommandLineRunner implements CommandLineRunner, EnvironmentAware {
    @Override
    public void run(String... args) throws Exception {
        log.info("AwareCommandLineRunner running...");
    }
    @Override
    public void setEnvironment(Environment environment) {
        String redisHost = environment.getProperty("redis-host");
        log.info("redis-host is {}", redisHost);
    }
}

SpringApplication啟動代碼如下

package geek.springboot.application;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Properties;
@Slf4j
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        // 添加redis-host配置  
        Properties properties = new Properties();
        properties.setProperty("redis-host", "127.0.0.1");
        application.setDefaultProperties(properties);
        application.run(args);
    }
}

啟動輸出 2023-08-27 19:01:15.198 INFO 56188 --- [ main] g.s.a.runner.AwareCommandLineRunner : redis-host is 127.0.0.1

自定義Aware

新建一個RedisConfig配置類

package geek.springboot.application.configuration;
import lombok.Data;
import org.springframework.stereotype.Component;
@Data
@Component
public class RedisConfig {
    private String ip = "127.0.0.1";
    private Integer port = 6379;
    @Override
    public String toString() {
        return "RedisConfig{" +
                "ip='" + ip + ''' +
                ", port=" + port +
                '}';
    }
}

創(chuàng)建一個RedisAware接口,Bean實現(xiàn)該接口即可獲取RedisConfig

package geek.springboot.application.aware;
import geek.springboot.application.configuration.RedisConfig;
import org.springframework.beans.factory.Aware;
/**
 * 自定義Aware
 *
 * @author Bruse
 */
public interface RedisAware extends Aware {
    void setRedisConfig(RedisConfig config);
}

創(chuàng)建一個RedisAwareProcessor,實現(xiàn)BeanPostProcessor接口,由它具體負(fù)責(zé)將RedisConfig注入實現(xiàn)了RedisAware接口的Bean。 為什么要實現(xiàn)BeanPostProcessor后邊的原理分析會提及。

package geek.springboot.application.aware;
import geek.springboot.application.configuration.RedisConfig;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
/**
 * 自定義RedisAwareProcessor
 *
 * @author Bruse
 */
@Component
public class RedisAwareProcessor implements BeanPostProcessor {
    @Autowired
    private ApplicationContext context;
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 判斷當(dāng)前Bean是否實現(xiàn)RedisAware
        if (bean instanceof RedisAware) {
            // 強轉(zhuǎn),調(diào)用setRedisConfig方法注入RedisConfig
            ((RedisAware) bean).setRedisConfig(context.getBean(RedisConfig.class));
        }
        return bean;
    }
}

AwareCommandLineRunner實現(xiàn)RedisAware接口

package geek.springboot.application.runner;
import geek.springboot.application.aware.RedisAware;
import geek.springboot.application.configuration.RedisConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class AwareCommandLineRunner implements CommandLineRunner, EnvironmentAware, RedisAware {
    @Override
    public void run(String... args) throws Exception {
        log.info("AwareCommandLineRunner running...");
    }
    @Override
    public void setEnvironment(Environment environment) {
        String redisHost = environment.getProperty("redis-host");
        log.info("redis-host is {}", redisHost);
    }
    @Override
    public void setRedisConfig(RedisConfig config) {
        log.info("redis config: {}", config.toString());
    }
}

啟動SpringApplication,輸出如下

2023-08-27 19:08:36.641 INFO 79920 --- [ main] g.s.a.runner.AwareCommandLineRunner : redis config: RedisConfig{ip='127.0.0.1', port=6379}

Aware原理

AwareCommandLineRunnersetEnvironment方法打上斷點,根據(jù)調(diào)用棧可以看到是在ApplicationContextAwareProcessorinvokeAwareInterfaces()方法中調(diào)用setEnvironment()方法進Environment注入的

接著再往上查找,可以看到invokeAwareInterfaces()方法又是在postProcessBeforeInitialization()中調(diào)用的

ApplicationContextAwareProcessor正好實現(xiàn)了BeanPostProcessor接口。這也就是為什么上邊自定義Aware實現(xiàn)時,需要創(chuàng)建一個RedisAwareProcessor并實現(xiàn)BeanPostProcessor的原因

再往上查看調(diào)用棧的話,可以理清完整的從上到下Aware調(diào)用鏈路

  • 調(diào)用AbstractAutowireCapableBeanFactorydoCreateBean()方法
  • 調(diào)用AbstractAutowireCapableBeanFactoryinitializeBean()方法
  • 調(diào)用AbstractAutowireCapableBeanFactoryapplyBeanPostProcessorsBeforeInitialization()方法
  • 調(diào)用ApplicationContextAwareProcessorpostProcessBeforeInitialization()方法
  • 調(diào)用ApplicationContextAwareProcessorinvokeAwareInterfaces()方法
  • 調(diào)用Aware接口實現(xiàn)的方法

doCreateBean其實涉及到SpringBoot中Bea初始化的內(nèi)容,可以看這一篇SpringBoot Bean實例化流程解析_java_腳本之家 (jb51.net)

以上就是SpringBoot中Aware接口使用及原理解析的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Aware接口的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringCloud OpenFeign與Ribbon客戶端配置詳解

    SpringCloud OpenFeign與Ribbon客戶端配置詳解

    在springcloud中,openfeign是取代了feign作為負(fù)載均衡組件的,feign最早是netflix提供的,他是一個輕量級的支持RESTful的http服務(wù)調(diào)用框架,內(nèi)置了ribbon,而ribbon可以提供負(fù)載均衡機制,因此feign可以作為一個負(fù)載均衡的遠(yuǎn)程服務(wù)調(diào)用框架使用
    2022-11-11
  • Java中操作Xml使用方法備忘錄(Hutool工具類XmlUtil、XStream)

    Java中操作Xml使用方法備忘錄(Hutool工具類XmlUtil、XStream)

    這篇文章主要給大家介紹了關(guān)于Java中操作Xml使用方法(Hutool工具類XmlUtil、XStream)的相關(guān)資料,XMLUtil是一個工具類,主要用于讀取XML配置文件并提供相應(yīng)的操作方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • SpringBoot?屬性配置中獲取值的方式

    SpringBoot?屬性配置中獲取值的方式

    這篇文章主要介紹了SpringBoot?屬性配置中獲取值的方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 詳解Java中的實例初始化塊(IIB)

    詳解Java中的實例初始化塊(IIB)

    在本篇文章里我們針對Java中的實例初始化塊(IIB)做想詳細(xì)分析,有需要的朋友們可以跟著學(xué)習(xí)參考下。
    2018-10-10
  • Deepin系統(tǒng)安裝eclipse2021-03及CDT插件的安裝教程

    Deepin系統(tǒng)安裝eclipse2021-03及CDT插件的安裝教程

    本教程教大家deepin20.1操作系統(tǒng)上安裝eclipse_2021-03版的詳細(xì)步驟及CDT插件的安裝方法,通過圖文展示的非常明了,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-06-06
  • Java中的TreeSet源碼解讀

    Java中的TreeSet源碼解讀

    這篇文章主要介紹了Java中的TreeSet源碼解讀,TreeSet 是一個 有序集合,它擴展了 AbstractSet 類并實現(xiàn)了 NavigableSet 接口,對象根據(jù)其自然順序以升序排序和存儲,該 TreeSet 中使用 平衡樹,更具體的一個 紅黑樹,需要的朋友可以參考下
    2023-09-09
  • 常用Java排序算法詳解

    常用Java排序算法詳解

    本文主要介紹了java的七種常見排序算法的實現(xiàn),對選擇排序、插入排序、冒泡排序、歸并排序、快速排序、希爾排序、最小堆排序進行原理分析與實例介紹,具有很好的參考價值。下面就跟著小編一起來看下吧
    2016-12-12
  • Java8之lambda最佳實踐_動力節(jié)點Java學(xué)院整理

    Java8之lambda最佳實踐_動力節(jié)點Java學(xué)院整理

    在8 里面Lambda是最火的主題,不僅僅是因為語法的改變,更重要的是帶來了函數(shù)式編程的思想,我覺得優(yōu)秀的程序員,有必要學(xué)習(xí)一下函數(shù)式編程的思想以開闊思路
    2017-06-06
  • SpringBoot接入ftp/ftps并上傳文件和配置的代碼指南

    SpringBoot接入ftp/ftps并上傳文件和配置的代碼指南

    接入ftp服務(wù)器,在springboot上實現(xiàn)起來也不算復(fù)雜,本文主要講下如何在springboot下接入ftp服務(wù)上傳文件,并對出現(xiàn)的問題做一些記錄,ftp服務(wù)的參數(shù)配置等,需要的朋友可以參考下
    2024-12-12
  • Java的抽象方法和抽象類實例詳解

    Java的抽象方法和抽象類實例詳解

    這篇文章主要介紹了Java的抽象方法和抽象類,結(jié)合實例形式詳細(xì)分析了java抽象方法和抽象類的相關(guān)原理、使用方法及操作注意事項,需要的朋友可以參考下
    2019-09-09

最新評論