0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

剖析Spring中最常用的擴展點(下)

jf_78858299 ? 來源:蘇三說技術(shù) ? 作者:蘇三說技術(shù) ? 2023-02-15 16:07 ? 次閱讀

7.修改BeanDefinition

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

如果想修改BeanDefinition對象中的屬性,該怎么辦呢?

答:我們可以實現(xiàn)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", "蘇三說技術(shù)");
        defaultListableBeanFactory.registerBeanDefinition("user", beanDefinitionBuilder.getBeanDefinition());
    }
}

在postProcessBeanFactory方法中,可以獲取BeanDefinition的相關(guān)對象,并且修改該對象的屬性。

8.初始化Bean前后

有時,你想在初始化Bean前后,實現(xiàn)一些自己的邏輯。

這時可以實現(xiàn):BeanPostProcessor接口。

該接口目前有兩個方法:

  • postProcessBeforeInitialization 該在初始化方法之前調(diào)用。
  • postProcessAfterInitialization 該方法再初始化方法之后調(diào)用。

例如:

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof User) {
            ((User) bean).setUserName("蘇三說技術(shù)");
        }
        return bean;
    }
}

如果spring中存在User對象,則將它的userName設(shè)置成:蘇三說技術(shù)。

其實,我們經(jīng)常使用的注解,比如:@Autowired、@Value、@Resource、@PostConstruct等,是通過AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor實現(xiàn)的。

9.初始化方法

目前spring中使用比較多的初始化bean的方法有:

  1. 使用@PostConstruct注解
  2. 實現(xiàn)InitializingBean接口

9.1 使用@PostConstruct注解

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

在需要初始化的方法上增加@PostConstruct注解,這樣就有初始化的能力。

9.2 實現(xiàn)InitializingBean接口

@Service
public class BService implements InitializingBean {

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

實現(xiàn)InitializingBean接口,重寫afterPropertiesSet方法,該方法中可以完成初始化功能。

10.關(guān)閉容器前

有時候,我們需要在關(guān)閉spring容器前,做一些額外的工作,比如:關(guān)閉資源文件等。

這時可以實現(xiàn)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容器銷毀前,會調(diào)用該destroy方法,做一些額外的工作。

通常情況下,我們會同時實現(xiàn)InitializingBean和DisposableBean接口,重寫初始化方法和銷毀方法。

11.自定義作用域

我們都知道spring默認(rèn)支持的Scope只有兩種:

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

spring web又對Scope進(jìn)行了擴展,增加了:

  • RequestScope 同一次請求從spring容器中獲取到的bean都是同一個對象。
  • SessionScope 同一個會話從spring容器中獲取到的bean都是同一個對象。

即便如此,有些場景還是無法滿足我們的要求。

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

這就需要自定義Scope了。

第一步實現(xiàn)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;
    }
}

第二步將新定義的Scope注入到spring容器中:

@Component
public class ThreadLocalBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.registerScope("threadLocalScope", new ThreadLocalScope());
    }
}

第三步使用新定義的Scope:

@Scope("threadLocalScope")
@Service
public class CService {
    public void add() {
    }
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    338

    瀏覽量

    14295
  • AOP
    AOP
    +關(guān)注

    關(guān)注

    0

    文章

    40

    瀏覽量

    11084
  • IOC
    IOC
    +關(guān)注

    關(guān)注

    0

    文章

    28

    瀏覽量

    10080
收藏 人收藏

    評論

    相關(guān)推薦

    Spring框架的設(shè)計理念

    Spring作為現(xiàn)在最優(yōu)秀的框架之一,已被廣泛的使用,51CTO也曾經(jīng)針對Spring框架中的hqC應(yīng)用做過報道。本文將從另外一個視角試圖剖析Spring框架的作者設(shè)計
    發(fā)表于 07-15 08:17

    電路中最常見到的電容使用方法

    基于電容常用功能,詳細(xì)介紹各功能應(yīng)用電路中最常見到的電容使用方法
    發(fā)表于 03-17 08:08

    請問射擊探測器中最常用的口徑是什么?

    射擊探測器中最常用的口徑是什么?
    發(fā)表于 04-12 06:56

    開關(guān)電源中最常用的電阻有哪些呢

    一 電阻1.開關(guān)電源中最常用的電阻有貼片電阻、插件色環(huán)電阻、壓敏電阻、熱敏電阻等。2.貼片電阻2.1 貼片電阻:主要按封裝和功率來分,常用的有0402 1/16W; 0603 1/10W; 0805
    發(fā)表于 12-29 06:14

    單片機系統(tǒng)中最常用的通信協(xié)議有幾種

    )、MOSI(主機輸出從機輸入Master Output/Slave Input)和MISO(主機輸入從機輸出Master Input/Slave Output)。單片機系統(tǒng)中最常用的通信協(xié)議有三種,分...
    發(fā)表于 02-17 07:43

    單片機系統(tǒng)中最常用的三種通信協(xié)議是什么?

    單片機系統(tǒng)中最常用的三種通信協(xié)議是什么?
    發(fā)表于 02-17 06:03

    EMC問題中最常用的手段RC濾波詳細(xì)資料說明

    讓我們一起來看看處理 EMC 問題中最常用的手段 -RC 濾波。本文介紹了濾波的概念,并詳細(xì)說明了電阻 - 電容(RC)低通濾波器的用途和特性。
    發(fā)表于 12-25 07:08 ?8次下載
    EMC問題<b class='flag-5'>中最常用</b>的手段RC濾波詳細(xì)資料說明

    聯(lián)網(wǎng)應(yīng)用中最常用的傳感器是什么?

    環(huán)境、運動、光電/圖像和健康監(jiān)測傳感器是物聯(lián)網(wǎng)應(yīng)用中最常用的傳感器類型
    的頭像 發(fā)表于 08-16 11:26 ?930次閱讀

    Spring中最常用的11個擴展

    除此之外,我們在使用spring的過程中,有沒有發(fā)現(xiàn)它的擴展能力非常強。由于這個優(yōu)勢的存在,讓spring擁有強大的包容能力,讓很多第三方應(yīng)用能夠輕松投入spring的懷抱。比如:ro
    的頭像 發(fā)表于 01-11 10:31 ?844次閱讀

    剖析Spring中最常用擴展(上)

    我們一說到spring,可能第一個想到的是 `IOC`(控制反轉(zhuǎn)) 和 `AOP`(面向切面編程)。 沒錯,它們是spring的基石,得益于它們的優(yōu)秀設(shè)計,使得spring能夠從眾多優(yōu)秀框架中脫穎而出。
    的頭像 發(fā)表于 02-15 16:06 ?713次閱讀
    <b class='flag-5'>剖析</b><b class='flag-5'>Spring</b><b class='flag-5'>中最常用</b>的<b class='flag-5'>擴展</b><b class='flag-5'>點</b>(上)

    剖析Spring中最常用擴展(中)

    我們一說到spring,可能第一個想到的是 `IOC`(控制反轉(zhuǎn)) 和 `AOP`(面向切面編程)。 沒錯,它們是spring的基石,得益于它們的優(yōu)秀設(shè)計,使得spring能夠從眾多優(yōu)秀框架中脫穎而出。
    的頭像 發(fā)表于 02-15 16:06 ?473次閱讀
    <b class='flag-5'>剖析</b><b class='flag-5'>Spring</b><b class='flag-5'>中最常用</b>的<b class='flag-5'>擴展</b><b class='flag-5'>點</b>(中)

    基于spring的SPI擴展機制是如何實現(xiàn)的?

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

    Spring中11個最常用擴展分享1

    在使用spring的過程中,我們有沒有發(fā)現(xiàn)它的擴展能力很強呢?由于這個優(yōu)勢的存在,使得spring具有很強的包容性,所以很多第三方應(yīng)用或者框架可以很容易的投入到spring的懷抱中。今
    的頭像 發(fā)表于 05-11 10:48 ?524次閱讀

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

    在使用spring的過程中,我們有沒有發(fā)現(xiàn)它的擴展能力很強呢?由于這個優(yōu)勢的存在,使得spring具有很強的包容性,所以很多第三方應(yīng)用或者框架可以很容易的投入到spring的懷抱中。今
    的頭像 發(fā)表于 05-11 10:48 ?357次閱讀

    講一失效分析中最常用的輔助實驗手段:亮點分析(EMMI)

    EMMI:Emission microscopy 。與SEM,F(xiàn)IB,EB等一起作為最常用的失效分析手段。
    的頭像 發(fā)表于 06-12 18:21 ?6480次閱讀
    講一<b class='flag-5'>下</b>失效分析<b class='flag-5'>中最常用</b>的輔助實驗手段:亮點分析(EMMI)