SpringIoc源碼(八)- ApplicationContext(四)- refresh(postProcessBeanFactory)

目錄

postProcessBeanFactory

1、AbstractRefreshableWebApplicationContext

1)、ServletContextAwareProcessor

2)、registerWebApplicationScopes

3)、registerEnvironmentBeans

2、AnnotationConfigServletWebServerApplicationContext

1)、WebApplicationContextServletContextAwareProcessor

2)、registerWebApplicationScopes

3、AnnotationConfigReactiveWebServerApplicationContext


postProcessBeanFactory

    允許在上下文子類中對bean工廠進行後處理,AbstractApplicationContext中方法爲空,實現的基本都是Web相關的子類,對javax.servlet.ServletContextjavax.servlet.ServletConfig以及Scope爲(Request、application)的處理。

1、AbstractRefreshableWebApplicationContext

    Spring Boot之前的Web類型項目,就會在該父類(AbstractRefreshableWebApplicationContext)中實現該方法,而當前的servletContext和servletConfig信息會在web.xml初始化時傳過來,在後面SpringMVC中進行分析。其子類有:

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

1)、ServletContextAwareProcessor

    添加了一個ServletContextAwareProcessor類型的BeanPostProcessor,只是添加調用在後面。如果Bean實現了ServletContextAware或者ServletConfigAware,則會在生命週期的中回調設置servletContext和servletConfig信息,回調實現正是ServletContextAwareProcessor,所以需要添加忽略接口。

2)、registerWebApplicationScopes

public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
                                                @Nullable ServletContext sc) {
    beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
    beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
    if (sc != null) {
        ServletContextScope appScope = new ServletContextScope(sc);
        beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
        // Register as ServletContext attribute, for ContextCleanupListener to detect it.
        sc.setAttribute(ServletContextScope.class.getName(), appScope);
    }

    beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
    beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
    beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
    beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
    if (jsfPresent) {
        FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
    }
}

    在WebApplicationContextUtils中,註冊Scope信息RequestScope和SessionScope,到AbstractApplicationContext的scopes中。但是基本都會使用singleton類型的scope,所以就不分析了。registerResolvableDependency註冊Servlet相關依賴。

 

3)、registerEnvironmentBeans

    也是在WebApplicationContextUtils中,將ServletContext相關的環境注入爲Bean。servletContextservletConfigcontextParameterscontextAttributes

public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf,
                                            @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
    if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
        bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
    }

    if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
        bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);
    }

    if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
        Map<String, String> parameterMap = new HashMap<>();
        if (servletContext != null) {
            Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();
            while (paramNameEnum.hasMoreElements()) {
                String paramName = (String) paramNameEnum.nextElement();
                parameterMap.put(paramName, servletContext.getInitParameter(paramName));
            }
        }
        if (servletConfig != null) {
            Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();
            while (paramNameEnum.hasMoreElements()) {
                String paramName = (String) paramNameEnum.nextElement();
                parameterMap.put(paramName, servletConfig.getInitParameter(paramName));
            }
        }
        bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
                Collections.unmodifiableMap(parameterMap));
    }

    if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {
        Map<String, Object> attributeMap = new HashMap<>();
        if (servletContext != null) {
            Enumeration<?> attrNameEnum = servletContext.getAttributeNames();
            while (attrNameEnum.hasMoreElements()) {
                String attrName = (String) attrNameEnum.nextElement();
                attributeMap.put(attrName, servletContext.getAttribute(attrName));
            }
        }
        bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,
                Collections.unmodifiableMap(attributeMap));
    }
}

 

2、AnnotationConfigServletWebServerApplicationContext

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // super爲AbstractApplicationContext,爲空方法
    super.postProcessBeanFactory(beanFactory);
    if (!ObjectUtils.isEmpty(this.basePackages)) {
        this.scanner.scan(this.basePackages);
    }
    if (!this.annotatedClasses.isEmpty()) {
        this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
    }
}

當爲初始化Spring boot類型時候,

SpringApplication springApplication = new SpringApplication(KevinToolApplication.class);
springApplication.setWebApplicationType(WebApplicationType.SERVLET);
springApplication.run(args);

    初始化AnnotationConfigReactiveWebServerApplicationContext類型,並且當前basePackagesannotatedClasses都爲空,父類ServletWebServerApplicationContext中方法如下

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    registerWebApplicationScopes();
}

     ServletContextAware添加到忽略,同上面相同。

1)、WebApplicationContextServletContextAwareProcessor

父類是ServletContextAwareProcessor並且實現了接口BeanPostProcessor,那麼在bean實現了該接口回調時,父類的postProcessBeforeInitialization中會回調setServletContextsetServletConfig方法,將Servlet信息進行注入。

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (getServletContext() != null && bean instanceof ServletContextAware) {
        ((ServletContextAware) bean).setServletContext(getServletContext());
    }
    if (getServletConfig() != null && bean instanceof ServletConfigAware) {
        ((ServletConfigAware) bean).setServletConfig(getServletConfig());
    }
    return bean;
}

2)、registerWebApplicationScopes

private void registerWebApplicationScopes() {
    ExistingWebApplicationScopes existingScopes = new 
        ExistingWebApplicationScopes(getBeanFactory());
    WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());
    existingScopes.restore();
}

 

 

 

 

3、AnnotationConfigReactiveWebServerApplicationContext

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // super爲AbstractApplicationContext,爲空方法
    super.postProcessBeanFactory(beanFactory);
    if (!ObjectUtils.isEmpty(this.basePackages)) {
        this.scanner.scan(this.basePackages);
    }
    if (!this.annotatedClasses.isEmpty()) {
        this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
    }
}

        當爲初始化Spring boot類型時候,

SpringApplication springApplication = new SpringApplication(KevinToolApplication.class);
springApplication.setWebApplicationType(WebApplicationType.REACTIVE);
springApplication.run(args);

    初始化AnnotationConfigReactiveWebServerApplicationContext類型,只是父類AbstractApplicationContext中該方法爲空,並且當前basePackagesannotatedClasses都爲空。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章