在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Spring中11個最常用的擴展點分享2

jf_78858299 ? 來源:JAVA旭陽 ? 作者:JAVA旭陽 ? 2023-05-11 10:48 ? 次閱讀

5.1 通用類

這種引入方式是最簡單的,引入的類會被實例化為一個bean對象。

public class A {
}

@Import(A.class)
@Configuration
public class TestConfiguration {

}

通過@Import注解引入類A,spring可以自動實例化A對象,然后在需要使用的地方通過注解@Autowired注入:

@Autowired
private A a;

5.2 配置類

這種引入方式是最復雜的,因為@Configuration支持還支持多種組合注解,比如:

  • @Import
  • @ImportResource
  • @PropertySource
public class A {
}

public class B {
}

@Import(B.class)
@Configuration
public class AConfiguration {

    @Bean
    public A a() {
        return new A();
    }
}

@Import(AConfiguration.class)
@Configuration
public class TestConfiguration {
}

@Configuration注解的配置類通過@Import注解導入,配置類@Import@ImportResource相關注解引入的類會一次性全部遞歸引入@PropertySource所在的屬性。

5.3 ImportSelector

該導入方法需要實現ImportSelector接口

public class AImportSelector implements ImportSelector {

    private static final String CLASS_NAME = "com.sue.cache.service.test13.A";

    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{CLASS_NAME};
    }
}

@Import(AImportSelector.class)
@Configuration
public class TestConfiguration {
}

這種方法的好處是selectImports方法返回的是一個數組,也就是說可以同時引入多個類,非常方便。

5.4 ImportBeanDefinitionRegistrar

該導入方法需要實現ImportBeanDefinitionRegistrar接口:

public class AImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(A.class);
        registry.registerBeanDefinition("a", rootBeanDefinition);
    }
}

@Import(AImportBeanDefinitionRegistrar.class)
@Configuration
public class TestConfiguration {
}

這種方法是最靈活的。容器注冊對象可以在registerBeanDefinitions方法中獲取,可以手動創建BeanDefinition注冊到BeanDefinitionRegistry種。

6. 當工程啟動時

有時候我們需要在項目啟動的時候自定義一些額外的功能,比如加載一些系統參數,完成初始化,預熱本地緩存等。我們應該做什么?

好消息是 SpringBoot 提供了:

  • CommandLineRunner
  • ApplicationRunner

這兩個接口幫助我們實現了上面的需求。

它們的用法很簡單,以ApplicationRunner接口為例:

@Component
public class TestRunner implements ApplicationRunner {

    @Autowired
    private LoadDataService loadDataService;

    public void run(ApplicationArguments args) throws Exception {
        loadDataService.load();
    }
}

實現ApplicationRunner接口,重寫run方法,在該方法中實現您的自定義需求。

如果項目中有多個類實現了ApplicationRunner接口,如何指定它們的執行順序?

答案是使用@Order(n)注解,n的值越小越早執行。當然,順序也可以通過@Priority注解來指定。

7. 修改BeanDefinition

在實例化Bean對象之前,Spring IOC需要讀取Bean的相關屬性,保存在BeanDefinition對象中,然后通過BeanDefinition對象實例化Bean對象。

如果要修改BeanDefinition對象中的屬性怎么辦?

答案 :我們可以實現 BeanFactoryPostProcessor 接口。

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
        beanDefinitionBuilder.addPropertyValue("id", 123);
        beanDefinitionBuilder.addPropertyValue("name", "Tom");
        defaultListableBeanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());
    }
}

postProcessBeanFactory方法中,可以獲取BeanDefinition的相關對象,修改對象的屬性。

8. 初始化 Bean 前和后

有時,您想在 bean 初始化前后實現一些您自己的邏輯。

這時候就可以實現:BeanPostProcessor接口。

該接口目前有兩個方法:

  • postProcessBeforeInitialization:應該在初始化方法之前調用。
  • postProcessAfterInitialization:此方法在初始化方法之后調用。
@Component
    public class MyBeanPostProcessor implements BeanPostProcessor {

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof User) {
                ((User) bean).setUserName("Tom");
            }
            return bean;
        }
    }

我們經常使用的@Autowired@Value@Resource@PostConstruct等注解都是通過AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor來實現的。

9. 初始化方法

目前在Spring中初始化bean的方式有很多種:

  1. 使用@PostConstruct注解
  2. 實現InitializingBean接口

9.1 使用 @PostConstruct

@Service
public class AService {
    @PostConstruct
    public void init() {
        System.out.println("===init===");
    }
}

為需要初始化的方法添加注解@PostConstruct,使其在Bean初始化時執行。

9.2 實現初始化接口InitializingBean

@Service
public class BService implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("===init===");
    }
}

實現InitializingBean接口,重寫afterPropertiesSet方法,在該方法中可以完成初始化功能。

10. 關閉Spring容器前

有時候,我們需要在關閉spring容器之前做一些額外的工作,比如關閉資源文件。

此時你可以實現 DisposableBean 接口并重寫它的 destroy 方法。

@Service
public class DService implements InitializingBean, DisposableBean {

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean destroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean afterPropertiesSet");
    }
}

這樣,在spring容器銷毀之前,會調用destroy方法做一些額外的工作。

通常我們會同時實現InitializingBeanDisposableBean接口,重寫初始化方法和銷毀方法。

11. 自定義Beanscope

我們都知道spring core默認只支持兩種Scope

  • Singleton單例,從spring容器中獲取的每一個bean都是同一個對象。
  • prototype多實例,每次從spring容器中獲取的bean都是不同的對象。

Spring Web 再次擴展了 Scope,添加

  • RequestScope:同一個請求中從spring容器中獲取的bean都是同一個對象。
  • SessionScope:同一個session從spring容器中獲取的bean都是同一個對象。

盡管如此,有些場景還是不符合我們的要求。

比如我們在同一個線程中要從spring容器中獲取的bean都是同一個對象,怎么辦?

答案 :這需要一個自定義范圍。

  1. 實現 Scope 接口
public class ThreadLocalScope implements Scope {
    private static final ThreadLocal THREAD_LOCAL_SCOPE = new ThreadLocal();

    @Override
    public Object get(String name, ObjectFactory? objectFactory) {
        Object value = THREAD_LOCAL_SCOPE.get();
        if (value != null) {
            return value;
        }

        Object object = objectFactory.getObject();
        THREAD_LOCAL_SCOPE.set(object);
        return object;
    }

    @Override
    public Object remove(String name) {
        THREAD_LOCAL_SCOPE.remove();
        return null;
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
    }

    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }

    @Override
    public String getConversationId() {
        return null;
    }
}
  1. 將新定義的Scope注入到Spring容器中
@Component
public class ThreadLocalBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.registerScope("threadLocalScope", new ThreadLocalScope());
    }
}
  1. 使用新定義的Scope
@Scope("threadLocalScope")
@Service
public class CService {
    public void add() {
    }
}

總結

本文總結了Spring中很常用的11個擴展點,可以在Bean創建、初始化到銷毀各個階段注入自己想要的邏輯,也有Spring MVC相關的攔截器等擴展點,希望對大家有幫助。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 轉換器
    +關注

    關注

    27

    文章

    8745

    瀏覽量

    148064
  • 框架
    +關注

    關注

    0

    文章

    403

    瀏覽量

    17543
  • spring
    +關注

    關注

    0

    文章

    340

    瀏覽量

    14392
收藏 人收藏

    評論

    相關推薦

    什么是java spring

    的事情。然而,Spring的用途不僅限于服務器端的開發。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring受益。Spring是一
    發表于 09-11 11:16

    Spring工作原理

    Spring所提供的這些服務和功能。Spring里用的最經典的一設計模式就是:模板方法模式。(這里我都不介紹了,是一常用的設計模式)
    發表于 07-10 07:41

    啟動Spring Boot項目應用的三種方法

    基礎。我們知道了Spring Boot是什么了,那么我們又該如何啟動Spring Boot應用呢?這里小編給大家推薦常用的三種方法。分別是IDEA編輯器啟動、命令啟動、java命令j
    發表于 01-14 17:33

    STM32時鐘系統最常用的知識

    ,講一最常用的知識。其它的型號大同小異。時鐘含義特點HSE外部高速時鐘信號一般選擇外接晶振,最常用的時鐘信號。電機驅動板外接12MhzHSI內部高速時鐘信號由單片...
    發表于 08-11 07:39

    高手最常用的電腦五組合鍵

    高手最常用的電腦五組合鍵 winkey+d : 這是高手最常用的第一快捷組合鍵。這個快捷鍵組合可以將桌面上的所有窗口瞬間最小化,無論是聊天的窗口還是
    發表于 02-24 10:41 ?61次下載

    Spring認證_什么是Spring GraphQL?

    數據整合 Spring GraphQL 支持使用 Querydsl 通過 Spring Data Querydsl 擴展 來獲取數據。Querydsl 提供了一種靈活但類型安全的方法,通過使用注釋
    的頭像 發表于 08-09 11:31 ?668次閱讀
    <b class='flag-5'>Spring</b>認證_什么是<b class='flag-5'>Spring</b> GraphQL?

    最常用11款Kubernetes工具

    助于改善 Kubernetes 開發人員的體驗。本文列出作者自己最常用11 款 Kubernetes 工具,并對它們進行了分類介紹。 Kubernetes 是一非常強大的容器編排平臺。但在
    的頭像 發表于 08-23 10:43 ?2206次閱讀

    10電源設計最常用公式的解析

    本文將為你解析10電源設計最常用的公式。非常實用,推薦收藏哦~
    發表于 02-10 11:40 ?8次下載
    10<b class='flag-5'>個</b>電源設計<b class='flag-5'>最常用</b>公式的解析

    Spring最常用11擴展

    除此之外,我們在使用spring的過程,有沒有發現它的擴展能力非常強。由于這個優勢的存在,讓spring擁有強大的包容能力,讓很多第三方應用能夠輕松投入
    的頭像 發表于 01-11 10:31 ?950次閱讀

    剖析Spring最常用擴展(上)

    我們一說到spring,可能第一想到的是 `IOC`(控制反轉) 和 `AOP`(面向切面編程)。 沒錯,它們是spring的基石,得益于它們的優秀設計,使得spring能夠從
    的頭像 發表于 02-15 16:06 ?795次閱讀
    剖析<b class='flag-5'>Spring</b>中<b class='flag-5'>最常用</b>的<b class='flag-5'>擴展</b><b class='flag-5'>點</b>(上)

    剖析Spring最常用擴展

    我們一說到spring,可能第一想到的是 `IOC`(控制反轉) 和 `AOP`(面向切面編程)。 沒錯,它們是spring的基石,得益于它們的優秀設計,使得spring能夠從
    的頭像 發表于 02-15 16:06 ?546次閱讀
    剖析<b class='flag-5'>Spring</b>中<b class='flag-5'>最常用</b>的<b class='flag-5'>擴展</b><b class='flag-5'>點</b>(<b class='flag-5'>中</b>)

    剖析Spring最常用擴展(下)

    我們一說到spring,可能第一想到的是 `IOC`(控制反轉) 和 `AOP`(面向切面編程)。 沒錯,它們是spring的基石,得益于它們的優秀設計,使得spring能夠從
    的頭像 發表于 02-15 16:07 ?515次閱讀

    基于spring的SPI擴展機制是如何實現的?

    基本上,你一說是基于 spring 的 SPI 擴展機制,再把spring.factories文件和EnableAutoConfiguration提一下,那么這個問題就答的八九不離十了。
    的頭像 發表于 03-07 09:17 ?1101次閱讀

    Spring11最常用擴展分享1

    在使用spring的過程,我們有沒有發現它的擴展能力很強呢?由于這個優勢的存在,使得spring具有很強的包容性,所以很多第三方應用或者框架可以很容易的投入到
    的頭像 發表于 05-11 10:48 ?593次閱讀

    Verilog最常用2種數據類型

    Verilog 最常用2 種數據類型就是線網(wire)與寄存器(reg),其余類型可以理解為這兩種數據類型的擴展或輔助。
    的頭像 發表于 05-29 16:27 ?2452次閱讀
    Verilog<b class='flag-5'>最常用</b>的<b class='flag-5'>2</b>種數據類型
    主站蜘蛛池模板: 国产一级片免费看 | 日本成人免费在线视频 | 成人永久免费视频网站在线观看 | 操美女的视频网站 | 视频二区中文字幕 | 俺要操| 色噜噜亚洲精品中文字幕 | 色777777女人色 | 激情五月婷婷久久 | 午夜人成 | 天天干天天干天天天天天天爽 | 国产特黄一级毛片特黄 | 国产在线观看色 | 欧美一级免费观看 | 狠狠色网站 | 99久热 | 性欧美videofree另类超大 | 五月婷婷激情综合网 | 国产片一级 | 色婷婷精品综合久久狠狠 | h视频在线观看免费网站 | 巨臀中文字幕一区二区翘臀 | 激情六月天 | 性视频软件 | 天天射天天干天天插 | 黄色软件入口 | 激情五月亚洲色图 | 天天舔天天干 | 老师叫我下面含着精子去上课 | 久久99精品一级毛片 | 亚洲人成毛片线播放 | 四虎永久免费观看 | 大尺度视频网站久久久久久久久 | 亚州视频一区二区 | 六月丁香深爱六月综合激情 | 最近2018年中文字幕大全一 | 免费一级黄色录像 | 成人a一级毛片免费看 | 久久婷婷五综合一区二区 | 视频二区中文字幕 | 天堂视频在线 |