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

  • Post author:
  • Post category:其他



目录


postProcessBeanFactory


1、AbstractRefreshableWebApplicationContext


1)、ServletContextAwareProcessor


2)、registerWebApplicationScopes


3)、registerEnvironmentBeans


2、AnnotationConfigServletWebServerApplicationContext


1)、WebApplicationContextServletContextAwareProcessor


2)、registerWebApplicationScopes


3、AnnotationConfigReactiveWebServerApplicationContext


postProcessBeanFactory

允许在上下文子类中对bean工厂进行后处理,AbstractApplicationContext中方法为空,实现的基本都是Web相关的子类,对

javax.servlet.ServletContext



javax.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。

servletContext



servletConfig



contextParameters



contextAttributes

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类型,并且当前

basePackages



annotatedClasses

都为空,父类

ServletWebServerApplicationContext

中方法如下

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

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

1)、WebApplicationContextServletContextAwareProcessor

父类是ServletContextAwareProcessor并且实现了接口BeanPostProcessor,那么在bean实现了该接口回调时,父类的

postProcessBeforeInitialization

中会回调


setServletContext





setServletConfig


方法,将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中该方法为空,并且当前

basePackages



annotatedClasses

都为空。



版权声明:本文为it_lihongmin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。