zoukankan      html  css  js  c++  java
  • Spring bean 的加载过程和生命周期

    【spring version : 4.1.6.RELEASE】

    使用spring的项目中,一般都会在web.xml中配置ContextLoaderListener,它就是spring ioc 的入口

    <!-- spring context listener -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

    入口:ContextLoaderListener.contextInitialized(ServletContextEvent)

    1。首先,创建一个上下文 WebApplicationContext context。使用默认的策略: XmlWebApplicationContext 的实例作为上下文。
    2. 将 XmlWebApplicationContext 强转成 ConfigurableWebApplicationContext ,设置 parent (是null)
    2. 调用 ContextLoader.configureAndRefreshWebApplicationContext 刷新上下文

    ContextLoader.configureAndRefreshWebApplicationContext 刷新上下文:
    1. 将ServletContext设置到 WebApplicationContext
    获取web.xml中配置的contextConfigLocation,设置到 WebApplicationContext 中
    2. wac.refresh() 刷新上下文

    刷新上下文:
    AbstractApplicationContext.refresh() 作如下工作:
    // Prepare this context for refreshing.
    【1】 prepareRefresh();

    // Tell the subclass to refresh the internal bean factory.
    【2】 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    1. 创建一个 DefaultListableBeanFactory 的实例。
    2. 加载bean的定义 loadBeanDefinitions(DefaultListableBeanFactory)
    (BeanDefinitionParser)

    // Prepare the bean factory for use in this context.
    【3】 prepareBeanFactory(beanFactory);
    1. 设置beanFactory的classLoader
    2. 设置 beanPostProcesser.
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    3. 注册spring内部指定的依赖类型和相应的自动注入值。

    // Register a special dependency type with corresponding autowired value.
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    所以,我们可以通过autowired的方式拿到ApplicationContext的实例

    4. Register default environment beans.

    // Allows post-processing of the bean factory in context subclasses.
    【4】 postProcessBeanFactory(beanFactory);
    beanFactory 后置处理,留给子类扩展,处理 beanFactory ,做类似【3】中的 prepareBeanFactory() 的事情,比如可以在这里添加 beanPostProcesser。
    context 的实例是 XmlWebApplicationContext,这个方法最后会调 AbstractRefreshableWebApplicationContext.postProcessBeanFactory(ConfigurableListableBeanFactory)

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 添加ServletContextAwareProcessor,用来处理实现了ServletContextAware接口的bean
    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);
    }

    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext) ---> 会去注册如下几个bean,所以在web项目中,我们可以直接使用@Resource来依赖注入这些bean

    beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
    beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
    beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
    beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());

    // Invoke factory processors registered as beans in the context.
    【5】 invokeBeanFactoryPostProcessors(beanFactory);
    执行beanFactory的postProcessor。(注意与beanPostProcessor区别开)
    里面会去找到所有的 BeanDefinitionRegistryPostProcessor 去执行 postProcessBeanDefinitionRegistry()。
    比如:ConfigurationClassPostProcessor、org.mybatis.spring.mapper.MapperScannerConfigurer


    // Register bean processors that intercept bean creation.
    【6】 registerBeanPostProcessors(beanFactory);
    注册beanPostProcessor,按顺序注册

    // Initialize message source for this context.
    【7】 initMessageSource();

    // Initialize event multicaster for this context.
    【8】 initApplicationEventMulticaster();
    初始化事件广播

    // Initialize other special beans in specific context subclasses.
    【9】 onRefresh();

    // Check for listener beans and register them.
    【10】 registerListeners();
    // 注册事件监听器,事件由ApplicationEventMulticaster去广播

    // Instantiate all remaining (non-lazy-init) singletons.
    【11】 finishBeanFactoryInitialization(beanFactory);
    解析 bean 的依赖,完成 bean 实例的初始化。
    1. 先创建 bean 的 proxy 。

    AbstractAutowireCapableBeanFactory.createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
    .....
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    // 【分析】:它会调用所有的 BeanPostProcessors 来对 bean 进行处理postProcessBeforeInitialization、postProcessAfterInitialization
    // 如果要生成代理对象的话,可想而知,BeanFactory在注册BeanDefinition时肯定注册了一个和生成代理相关的 BeanPostProcessor
    // 而我们在spring配置文件中配置了 <aop:aspectj-autoproxy proxy-target-class="true" /> ,它肯定会对应一个 BeanDefinitionParser 来解析这个标签。
    // 由此,我们又找到了 AspectJAutoProxyBeanDefinitionParser.parse(),这个方法就对 AnnotationAwareAspectJAutoProxyCreator 进行了注册,它间接实现了 BeanPostProcessor
    Object bean = resolveBeforeInstantiation(beanName, mbd);
    if (bean != null) {
    return bean;
    }
    ......

    2. 如果创建出来了的话,就返回bean的代理,否则就创建非代理的 bean
    里面会决定要不要创建 bean 的 proxy。(AbstractAutoProxyCreator.createProxy)

    // Last step: publish corresponding event.
    //Finish the refresh of this context, invoking the LifecycleProcessor's onRefresh() method and publishing the ContextRefreshedEvent.
    【12】 finishRefresh();

    推荐文章:https://www.jianshu.com/p/1dec08d290c1

  • 相关阅读:
    使用批处理文件(.bat)启动Java程序
    VARCHAR2(%n)和VARCHAR2(%n char)区别
    Truncate Table
    Ext4之杂七杂八
    Oracle导表
    关于hibernate的session.createSQLQuery(sql)直接调用底层SQL后,返回结果集的问题
    Ext4真是难(展开表格行,显示图表)
    Hadoop学习笔记【入门】
    魅蓝note 做Android真机调试
    11-java学习笔记-反射
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/6402391.html
Copyright © 2011-2022 走看看