日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

【Spring】Bean的LifeCycle(生命周期)

發布時間:2023/12/19 综合教程 33 生活家
生活随笔 收集整理的這篇文章主要介紹了 【Spring】Bean的LifeCycle(生命周期) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

菜瓜:水稻,上次說Bean的LifeCycle,還沒講完

水稻:啥?說人話?

菜瓜:spring,bean,生命周期

水稻:。。。那你真的是很棒棒哦!。。。bean生命周期的話,從BeanFactory、ApplicationContext和FactoryBean開始說起

我們知道(你不一定知道)BeanFactory是Spring訪問Bean容器的根接口,源碼的注釋: “The root interface for accessing a Spring bean container.”
而ApplicationContext繼承自BeanFactory,也就是說它具有BeanFactory的屬性和方法,并進一步完善(繼承其他的接口)
FactoryBean跟前兩個關系就不怎么大了,它是spring提供給用戶創建bean的口子,有一些bean創建過程復雜,或者依賴第三方包等(Mybatis-Spring中),可交給用戶自己創建

菜瓜:嗯。。陷入沉思。。(欲言又止)

水稻:講理論不給代碼就是耍流氓

package com.vip.qc.postprocessor;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

/**
 * @author QuCheng on 2020/6/15.
 */
@Component("fb")
public class FactoryBeanT implements FactoryBean<FactoryBeanT.CustomBean> {

    public FactoryBeanT() {
        System.out.println("實現FactoryBean接口的類自身被放在IOC一級緩存的容器里面,getObject的對象是在另一個緩存對象中");
    }

    @Override
    public CustomBean getObject() {
        return new CustomBean();
    }

    @Override
    public Class<?> getObjectType() {
        return CustomBean.class;
    }

    static class CustomBean {
        public CustomBean() {
            System.out.println("自定義bean");
        }
    }
}

測試方法
@Test
public void testTransa() {
    BeanFactory context = new AnnotationConfigApplicationContext(ComponentScanD.class);
    System.out.println("factoryBean : " + context.getBean("fb"));
    System.out.println("&factoryBean : " + context.getBean("&fb"));
}

測試結果

實現FactoryBean接口的類自身被放在IOC一級緩存的容器里面,getObject的對象是在另一個緩存對象中
自定義bean
factoryBean : com.vip.qc.postprocessor.FactoryBeanT$CustomBean@214b199c
&factoryBean : com.vip.qc.postprocessor.FactoryBeanT@20d3d15a

菜瓜:懂了,BeanFactory是Spring的核心--容器,ApplicationContext則是包裹容器的上下文,豐富容器的功能(資源加載,事件驅動等)。FactoryBean也是Spring擴展性的體現

水稻:WC,你這個總結提到了精髓。就是擴展性:如果BeanFactory是核心思想,那么其他的上下文,后置處理器,還是Aware接口等等,都是為了實現擴展

菜瓜:鋪墊說完了,開始生命周期唄

水稻:這次咱們反過來先看源碼,再看實驗,再總結

BeanFactory源碼注釋 - 定義了實現的生命周期

 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Chris Beams
 * @since 13 April 2001
 * @see BeanNameAware#setBeanName
 * @see BeanClassLoaderAware#setBeanClassLoader
 * @see BeanFactoryAware#setBeanFactory
 * @see org.springframework.context.ResourceLoaderAware#setResourceLoader
 * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
 * @see org.springframework.context.MessageSourceAware#setMessageSource
 * @see org.springframework.context.ApplicationContextAware#setApplicationContext
 * @see org.springframework.web.context.ServletContextAware#setServletContext
 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
 * @see InitializingBean#afterPropertiesSet
 * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
 * @see DisposableBean#destroy
 * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
 */
public interface BeanFactory {

BeanFactory源碼實現類

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            // BeanNameAware BeanFactoryAware ...
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // BeanPostProcessor Before  @PostConstruct
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // initMethod InitializingBean接口
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            // BeanPostProcessor after
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

實驗代碼

package com.vip.qc.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * @author QuCheng on 2020/6/14.
 */
@Component
public class BeanFactoryPostProcessorT implements BeanFactoryPostProcessor {

    public static final String BEAN_NAME = "initializingBeanT";

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition initializingBeanT = beanFactory.getBeanDefinition(BEAN_NAME);
        System.out.println("BeanFactoryPostProcessor bean " + initializingBeanT.getBeanClassName());
    }
}



package com.vip.qc.postprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * @author QuCheng on 2020/6/14.
 */
@Component
public class BeanPostProcessorT implements BeanPostProcessor {

    public static final String BEAN_NAMET = "initializingBeanT";

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (BEAN_NAMET.equals(beanName)) {
            InitializingBeanT processorT = ((InitializingBeanT) bean);
            System.out.println("BeanPostProcessor BeforeInitialization " + processorT);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (BEAN_NAMET.equals(beanName)){
            InitializingBeanT processorT = ((InitializingBeanT) bean);
            System.out.println("BeanPostProcessor AfterInitialization " + processorT);
        }
        return bean;
    }

}


package com.vip.qc.postprocessor;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @author QuCheng on 2020/6/14.
 */
@Component
public class InitializingBeanT implements BeanNameAware, InitializingBean, DisposableBean {

    public InitializingBeanT() {
        System.out.println("init無參構造 execute");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("@PostConstruct  execute");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("@PreDestroy  execute");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("InitializingBean afterPropertiesSet --> " + this.toString());
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("BeanNameAware : " + name);
    }

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


測試代碼
    @Test
    public void testLifeCycle() {
        AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(ComponentScanD.class);
        applicationContext.close();// 這里不關閉容器的話,注銷bean的方法會看不到打印
    }

測試結果

BeanFactoryPostProcessor bean com.vip.qc.postprocessor.InitializingBeanT
init無參構造 execute
BeanNameAware : initializingBeanT
BeanPostProcessor BeforeInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
@PostConstruct execute
InitializingBean afterPropertiesSet --> com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
BeanPostProcessor AfterInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
@PreDestroy execute
destroy

菜瓜:實現什么的不重要,接口才是爸爸呀,BeanFactory定義好了生命周期,下面的實現也只是實現罷了

水稻:哈哈,你說的對,一流的公司賣標準

菜瓜:這里怎么沒看到循環依賴的處理啊

水稻:是的。這里的源碼我只截取了bean初始化完成之后的接口調用。循環依賴的處理在它前面。來來來,繼續剛

菜瓜:剛不了剛不了,你一下子搞這么多玩意給我看,我哪看得完

水稻:您歇著,下次您什么時候想了解我再給您說

總結

BeanFactory已經定義了整個的生命周期,子類只是負責實現,demo演示也只是為了證實。我們更應該關注更上層的東西
ApplicationContext是對容器更精細化的包裝,提供了更完善的功能
FactoryBean是Spring擴展性的提現,可供用戶自己定義創建bean。擴展性提煉的很好

總結

以上是生活随笔為你收集整理的【Spring】Bean的LifeCycle(生命周期)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。