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都为空。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值