Spring启动流程(四)——BeanFactory后处理

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // ServletContextAwareProcessor中拿到应用上下文持有的servletContext引用和servletConfig引用
    // 添加ServletContextAwareProcessor后处理器
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
    
    // 在自动注入时忽略指定的依赖接口
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

    // 向WebApplicationContext使用的BeanFactory注册Web相关作用域对象
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    
    // 注册和Environment有关的beans
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);

WebApplicationContextUtils

该类位于包org.springframework.web.context.support是一个使检索指定ServletContext的根WebApplicationContext的便捷工具类。它如下工具方法:

  1. 在Web容器启动过程中注册Web相关作用域Bean(request/session/globalSession/application)
  2. 在Web容器启动过程中注册相应类型的工厂Bean ,依赖注入的Bean时能访问到正确的对象(ServletRequest/ServletResponse/HttpSession/WebRequest)
  3. 在Web容器启动过程中注册Web相关环境Bean
  4. 在Web容器启动过程中初始化Servlet propertySources
  5. 在客户化Web视图或者MVC action中,使用该工具类可以很方便地在程序中访问Spring应用上下文(application context)。

自定义作用域

Scope也称作用域,在Soring Ioc容器指其创建的Bean对象对其他Bean对象的请求可见范围,是用来声明IoC容器中的对象应该处的限定场景或者说该对象的存活空间,即在IOC容器在对象进入相应的Scope之前,生成并装配这些对象,在该对象不再处于这些scope的限定之后,容器通常会销毁这些对象。
诸如WebApplicationContext之类的ApplicationContext可以注册相对于标准作用域(Singleton/Prototype)的特定环境Scope作用域,例如:“request”和“session”作用域。
Bean的Scope作用域范围同样是可扩展的:即可以定义自己的范围,甚至重新定义现有范围,但不能覆盖内置的Singleton和Prototype范围。

// 从scope中根据名字返回对象
Object get(String name, ObjectFactory objectFactory);

// 从Scope中删除该对象
Object remove(String name);

// 注册的Scope被销毁或Scope中的指定对象被销毁时执行回调
void registerDestructionCallback(String name, Runnable destructionCallback);

// 获取Scope的会话标识符
String getConversationId();

ConfigurableBeanFactory接口中允许使用自定义的作用域范围扩展BeanFactory的标准作用域“ Singleton”和“ Prototype”,并为新的作用域范围进行注册。在编写好自定义Scope之后,需要让Spring容器识别新的Scope作用域。
在这里插入图片描述

代码方式注册

以下方法是在Spring容器中注册新Scope的主要方法,该方法在ConfigurableBeanFactory接口中定义:

// 第一个参数是与该Scope的全局唯一名称。在Spring容器中,此名称是Singleton和Prototype
// 第二个参数是希望注册和使用的自定义Scope实例
void registerScope(String scopeName, Scope scope);

如果已经写好了自己的自定义Scope实现,并且已经将其进行了注册:

Scope threadScope = new SimpleThreadScope();
beanFactory.registerScope("thread", threadScope);

然后就可以在配置文件中创建与自定义Scope规则对应的Bean定义:

<bean id="..." class="..." scope="thread"/>

配置方式注册

对于ApplicationContext来说,因为它可以自动识别并加载BeanFactoryPostProcessor,所以我们就可以直接在配置文件中,通过这个CustomScopeConfigurer注册来使新的Scope作用域范围生效。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                      http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="customerScope" value="cn.lzh.scope.CustomerScope"/>
            </map>
        </property>
    </bean>

    <bean id="human" class="cn.lzh.autowired.Human" scope="customerScope">
        <!-- 让Bean符合自定义的作用域 -->
        <!--<aop:scoped-proxy/>-->
    </bean>
</beans>

测试类

public class TestScope {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx =
                new ClassPathXmlApplicationContext("scope.xml");

        // 代码方式注册新的Scope作用域
        // ctx.getBeanFactory().registerScope("customerScope", new CustomerScope());

        System.out.println(ctx.getBeanFactory().getBeanDefinition("human").getScope());
        String scopes[] = ctx.getBeanFactory().getRegisteredScopeNames();
        for (String scope : scopes) {
            System.out.println(scope);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值