最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何實現(xiàn)bean初始化摧毀方法的注入

 更新時間:2023年04月28日 10:46:03   作者:Anoxia1  
這篇文章主要為大家介紹了如何實現(xiàn)bean初始化摧毀方法的注入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

實現(xiàn) bean 初始化、摧毀方法的配置與處理

spring支持我們自定義 bean 的初始化方法和摧毀方法。配置方式可以通過 xml 的 init-methoddestory-method配置,或者實現(xiàn) InitializingBeanDisposableBean接口,來完成自定義的初始化和bean的銷毀。 在項目開發(fā)過程中,相信最多看到的是 @PostConstruct 注解標(biāo)識的方法來進(jìn)行bean的初始化。

@PostConstruct 是 Spring Framework 提供的注解,可以用于在 Bean 實例化之后執(zhí)行初始化操作

通過xml配置定義初始化、摧毀方法

BeanDefinition 里面添加 initMethodName、和 destoryMethodName 屬性,來記錄通過配置注入的初始化和摧毀方法名稱。然后在解析 xml 文件的 cn.anoxia.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions方法中,完成 屬性的注入。

protected void doLoadBeanDefinitions(InputStream inputStream) throws Exception {
        Document doc = XmlUtil.readXML(inputStream);
        Element root = doc.getDocumentElement();
        NodeList childNodes = root.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            ....
            String initMethod = bean.getAttribute("init-method");
            String destroyMethod = bean.getAttribute("destroy-method");
            Class<?> clazz = Class.forName(calssName);
            String beanName = StrUtil.isNotEmpty(id) ? id : name;
            if (StrUtil.isEmpty(beanName)){
                beanName = StrUtil.lowerFirst(clazz.getSimpleName());
            }
            // 定義bean
            BeanDefinition beanDefinition = new BeanDefinition(clazz);
            // 設(shè)置初始化、摧毀方法
            beanDefinition.setInitMethodName(initMethod);
            beanDefinition.setDestoryMethodName(destroyMethod);
            ....
        }
    }

通過實現(xiàn)接口

實現(xiàn) InitializingBean,DisposableBean 并實現(xiàn)里面的方法,來自定義bean的初始化和摧毀方法

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

在 創(chuàng)建bean的過程中,完成方法的注入,區(qū)分xml配置與接口實現(xiàn)。

initMethod 方法的注入與執(zhí)行

@Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) {
        Object bean = null;
        try {
            bean = createBeanInstance(beanDefinition, beanName, args);
            // 注入屬性
            applyPropertyValues(beanName, bean, beanDefinition);
            // 提供給外部的擴(kuò)展包裝,執(zhí)行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置處理方法
            bean = initializeBean(beanName, bean, beanDefinition);
        } catch (Exception e) {
            throw new RuntimeException("bean create error!", e);
        }
        // 注冊實現(xiàn)了 DisposableBean 接口的 Bean 對象
        registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);
        registerSingleton(beanName, bean);
        return bean;
    }
private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) throws BeansException {
        // 1. 執(zhí)行 BeanPostProcess before 操作
        Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        try {
            // 執(zhí)行bean初始化方法
            invokeInitMethods(beanName,wrappedBean,beanDefinition);
        }catch (Exception e){
            throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e);
        }
        // 2. 執(zhí)行 BeanPostProcess after 操作
        wrappedBean = applyBeanPostProcessorsAfterInitialization(bean,beanName);
        return wrappedBean;
    }
private void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) throws Exception {
    // 如果是通過接口實現(xiàn),直接使用接口提供的方法    
    if (bean instanceof InitializingBean) {
            ((InitializingBean) bean).afterPropertiesSet();
        }
    // 通過xml配置,獲取方法執(zhí)行
        String initMethodName = beanDefinition.getInitMethodName();
        if (StrUtil.isNotEmpty(initMethodName)) {
            Method method = beanDefinition.getBeanClass().getMethod(initMethodName);
            // getMethod 已經(jīng)做了非空判斷
            if (null == method) {
                throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'");
            }
            method.invoke(bean);
        }
    }

destroyMethod 方法的注入與執(zhí)行

提供一個適配器、來完成xml和接口的適配處理。處理邏輯基本與 init方法相似

/**
 * bean 摧毀適配器
 * @author huangle
 * @date 2023/3/7 10:26
 */
public class DisposableBeanAdapter implements DisposableBean {
    /**
     * bean名字
     */
    private final String beanName;
    /**
     * bean
     */
    private final Object bean;
    /**
     * 銷毀方法名稱
     */
    private String destroyMethodName;
    public DisposableBeanAdapter(String beanName, Object bean, BeanDefinition beanDefinition) {
        this.beanName = beanName;
        this.bean = bean;
        this.destroyMethodName = beanDefinition.getDestoryMethodName();
    }
    @Override
    public void destroy() throws Exception {
        // 1. 實現(xiàn) DisposableBean 接口,完成摧毀擴(kuò)展
        if (bean instanceof DisposableBean) {
            ((DisposableBean) bean).destroy();
        }
        // 2. 通過xml配置 配置 destroy 方法 實現(xiàn)
        if (StrUtil.isNotEmpty(destroyMethodName) &amp;&amp; !(bean instanceof DisposableBean &amp;&amp; "destory".equals(destroyMethodName))) {
            Method destroyMethod = bean.getClass().getMethod(destroyMethodName);
            if (null == destroyMethod) {
                throw new BeansException("Couldn't find a destroy method named '" + destroyMethodName + "' on bean with name '" + beanName + "'");
            }
            destroyMethod.invoke(bean);
        }
    }
}

測試

userDao 通過xml配置初始化和摧毀方法,userService 通過繼承接口來實現(xiàn)方法。

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="userDao" class="cn.anoxia.springframework.beans.factory.support.UserDao" init-method="initMethod" destroy-method="destroyMethod"/>
    <bean id="userService" class="cn.anoxia.springframework.beans.factory.support.UserService">
        <property name="name" value="Anoxia"/>
        <property name="nickname" value="迪迦"/>
        <property name="userDao" ref="userDao"/>
    </bean>
<!--    <bean id="myBeanPostProcecssor" class="cn.anoxia.springframework.beans.factory.support.MyBeanPostProcecssor"/>-->
<!--    <bean id="myFactoryPostProcessor" class="cn.anoxia.springframework.beans.factory.support.MyBeanFactoryPostProcessor"/>-->
</beans>
public class UserService implements InitializingBean, DisposableBean{
    @Override
    public void destroy() throws Exception {
        System.out.println("userService執(zhí)行:destroy 方法");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("userService執(zhí)行:init 方法");
    }
}

測試結(jié)果

以上就是如何實現(xiàn)bean初始化摧毀方法的注入的詳細(xì)內(nèi)容,更多關(guān)于bean初始化摧毀方法注入的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談一下Java為什么不能使用字符流讀取非文本的二進(jìn)制文件

    淺談一下Java為什么不能使用字符流讀取非文本的二進(jìn)制文件

    這篇文章主要介紹了淺談一下為什么不能使用字符流讀取非文本的二進(jìn)制文件,剛學(xué)Java的IO流部分時,書上說只能使用字節(jié)流去讀取圖片、視頻等非文本二進(jìn)制文件,不能使用字符流,否則文件會損壞,需要的朋友可以參考下
    2023-04-04
  • java讀取resource目錄下文件的方法示例

    java讀取resource目錄下文件的方法示例

    這篇文章主要介紹了利用java讀取resource目錄下文件的方法,文中給出了詳細(xì)的示例代碼,相信對大家具有一定的參考借鑒,需要的朋友們下面來一起看看吧。
    2017-02-02
  • SpringBoot整合mybatis-plus快速入門超詳細(xì)教程

    SpringBoot整合mybatis-plus快速入門超詳細(xì)教程

    mybatis-plus 是一個 Mybatis 的增強(qiáng)工具,在 Mybatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡化開發(fā)、提高效率而生,本文給大家分享SpringBoot整合mybatis-plus快速入門超詳細(xì)教程,一起看看吧
    2021-09-09
  • Java Mybatis框架多表操作與注解開發(fā)詳解分析

    Java Mybatis框架多表操作與注解開發(fā)詳解分析

    MyBatis 是一款優(yōu)秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過簡單的 XML 或注解來配置和映射原始類型、接口和 Java POJO為數(shù)據(jù)庫中的記錄
    2021-10-10
  • Spring?Boot+Vue實現(xiàn)Socket通知推送的完整步驟

    Spring?Boot+Vue實現(xiàn)Socket通知推送的完整步驟

    最近工作中涉及消息通知功能的開發(fā),所以下面這篇文章主要給大家介紹了關(guān)于Spring?Boot+Vue實現(xiàn)Socket通知推送的完整步驟,文中通過實例代碼以及圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • java多線程編程之Synchronized關(guān)鍵字詳解

    java多線程編程之Synchronized關(guān)鍵字詳解

    這篇文章主要為大家詳細(xì)介紹了java多線程編程之Synchronized關(guān)鍵字,感興趣的朋友可以參考一下
    2016-05-05
  • android中GridView的用法示例

    android中GridView的用法示例

    這篇文章主要介紹了android中GridView的用法,對于Android初學(xué)者很有參考學(xué)習(xí)價值,需要的朋友可以參考下
    2014-08-08
  • SpringBoot集成MyBatis的分頁插件PageHelper實例代碼

    SpringBoot集成MyBatis的分頁插件PageHelper實例代碼

    這篇文章主要介紹了SpringBoot集成MyBatis的分頁插件PageHelper的相關(guān)操作,需要的朋友可以參考下
    2017-08-08
  • MyBatis的五種批量查詢實例總結(jié)

    MyBatis的五種批量查詢實例總結(jié)

    為了提高代碼的執(zhí)行效率,我們有時需要采用批量查詢的查詢方法,下面這篇文章主要給大家介紹了關(guān)于MyBatis的五種批量查詢的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • mybatis學(xué)習(xí)之路mysql批量新增數(shù)據(jù)的方法

    mybatis學(xué)習(xí)之路mysql批量新增數(shù)據(jù)的方法

    這篇文章主要介紹了mybatis學(xué)習(xí)之路mysql批量新增數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02

最新評論

孝义市| 翼城县| 固原市| 长乐市| 衡南县| 乌拉特前旗| 铜梁县| 长岭县| 南漳县| 达州市| 西藏| 闻喜县| 沙田区| 平原县| 北辰区| 密山市| 莱州市| 台东县| 文安县| 临武县| 松溪县| 朔州市| 平乡县| 宝鸡市| 金溪县| 喀喇沁旗| 和平区| 息烽县| 杭锦后旗| 丹江口市| 司法| 山东| 勃利县| 牡丹江市| 台山市| 天津市| 盖州市| 行唐县| 陇西县| 启东市| 鹰潭市|