天天看點

Spring Bean生命周期-prepareBeanFactory(五)

在ApplicationContext重新整理擷取beanFactory之後,開始準備context使用的beanFactory。這一步相對比較簡單,就是配置facotry的特性,比如:ClassLoader,post-processors等等

代碼如下:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        //讓BeanFactory使用context的class loader
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        // 配置bean factory的context回調
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

        // BeanFactory interface not registered as resolvable type in a plain factory.
        // MessageSource registered (and found for autowiring) as a bean.
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // Register default environment beans.
        // 注冊預設的environment bean
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }
           

分析

beanfactory的準備階段,比較簡單,主要明白準備階段操作的幾個方法。

beanFactory.addBeanPostProcessor

添加BeanPostProcessor,當bean被這個工廠建立的時候會用到PostProcessor, 在beanfactory中存儲了beanPostProcessors的清單,在生效的時候,清單中的PostProcessor都會執行。

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
           
beanFactory.ignoreDependencyInterface(Class<?> ifc)

在注入的時候忽略此方法指定的接口類。也就是指定的接口不會被注入進去。

如下,不會生效

@Autowire 
ResourceLoaderAware aware;
           
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
           
beanFactory.registerResolvableDependency(Class<?> dependencyType, Object autowiredValue)

注冊可以解析的依賴關系,當注入的類型為dependencyType的時候,注入autowiredValue。

注入類型與注入值的關系存儲在map中。

resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16);

// 注入類型為BeanFactory時,注入beanFactory(DefaultListableBeanFactory)
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);

//注入類型為ApplicationEventPublisher時,注入值為this(ApplicationContext)
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);

//注入類型為ApplicationContext時,注入值也為this(ApplicationContext)
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
           

額外

prepareBeanFactory主要做一些準備工作,沒有什麼邏輯,在Applicationcontext的refresh方法中往下看一步,執行

postProcessBeanFactory(beanFactory);
           

這一步Spring架構中沒有實作,留待我們自己實作。

最後

這次看了refresh方法中的prepareBeanFactory内容比較簡單,就不多說了。