中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么實現bean初始化摧毀方法的注入

發布時間:2023-04-28 11:26:45 來源:億速云 閱讀:127 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“怎么實現bean初始化摧毀方法的注入”,內容詳細,步驟清晰,細節處理妥當,希望這篇“怎么實現bean初始化摧毀方法的注入”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

實現 bean 初始化、摧毀方法的配置與處理

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

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

通過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);
            // 設置初始化、摧毀方法
            beanDefinition.setInitMethodName(initMethod);
            beanDefinition.setDestoryMethodName(destroyMethod);
            ....
        }
    }

通過實現接口

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

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

在 創建bean的過程中,完成方法的注入,區分xml配置與接口實現。

initMethod 方法的注入與執行

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

destroyMethod 方法的注入與執行

提供一個適配器、來完成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. 實現 DisposableBean 接口,完成摧毀擴展
        if (bean instanceof DisposableBean) {
            ((DisposableBean) bean).destroy();
        }
        // 2. 通過xml配置 配置 destroy 方法 實現
        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 通過繼承接口來實現方法。

<?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執行:destroy 方法");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("userService執行:init 方法");
    }
}

測試結果

怎么實現bean初始化摧毀方法的注入

讀到這里,這篇“怎么實現bean初始化摧毀方法的注入”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

云南省| 佛山市| 永兴县| 曲靖市| 上饶县| 大田县| 永清县| 庆城县| 顺昌县| 治多县| 休宁县| 黄龙县| 湖州市| 什邡市| 城步| 平阳县| 团风县| 德昌县| 吴忠市| 忻城县| 定安县| 浙江省| 咸宁市| 莱西市| 宜春市| 遂川县| 涿鹿县| 共和县| 同仁县| 都江堰市| 汕头市| 巢湖市| 社会| 玉溪市| 扬州市| 五家渠市| 城口县| 深州市| 汶上县| 英吉沙县| 烟台市|