Spring IOC-ContextLoaderListener
【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
Spring IOC-ContextLoaderListener的更多相关文章
- Spring学习进阶(二)Spring IoC
在使用Spring所提供的各种丰富而神奇的功能之前,必须在Spring IoC容器中装配好Bean,并建立Bean与Bean之间的关联关系.控制反转(Inverser of Control ioc)是 ...
- 一、Spring——IoC
IOC概述 Spring中IOC的概念,控制反转概念其实包含两个层面的意思,"控制"是接口实现类的选择控制权:而"反转"是指这种选择控制权从调用者转移到外部第三 ...
- 对Spring IoC容器实现的结构分析
本文的目标:从实现的角度来认识SpringIoC容器. 观察的角度:从外部接口,内部实现,组成部分,执行过程四个方面来认识SpringIoC容器. 本文的风格:首先列出SpringIoC的外部接口及内 ...
- spring IOC容器实例化Bean的方式与RequestContextListener应用
spring IOC容器实例化Bean的方式有: singleton 在spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在. prototype 每次从容器中调用Bean时, ...
- Spring IOC之基于JAVA的配置
基础内容:@Bean 和 @Configuration 在Spring中新的支持java配置的核心组件是 @Configuration注解的类和@Bean注解的方法. @Bean注解被用于表明一个方法 ...
- Spring框架学习02——Spring IOC 详解
1.Spring IOC的基本概念 IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理.当某个Java对象(调用者)需要调用 ...
- Spring IOC 容器源码分析
声明!非原创,本文出处 Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 S ...
- 【转】Spring学习---Spring IoC容器的核心原理
[原文] Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国. IoC和DI的基本概念 IoC(控制反转,英文含义:Inverse of Control)是Spr ...
- Spring IOC 源码分析
Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...
- Spring—Ioc
IoC容器,最主要的就是完成对象的创建以及维护对象的依赖关系等. 所谓控制反转,包括两部分:一是控制,二是反转,就是把传统方式需要由代码来实现对象的创建.维护对象的依赖关系,反转给容器来帮忙管理和实现 ...
随机推荐
- find命令查找包含指定内容的文件
find / | xargs grep function 查找系统根目录下面的所有文件的内容中包含有function字符串的文件列表. find .|xargs grep xfind . -exec ...
- C#7.0新语法
一.out输出参数 在以前使用out输出参数的时候,必须先定义变量,然后才能使用,例如: 先定义一个方法,方法参数是out类型的输出参数: private void DoNoting(out int ...
- Paxos算法细节详解(一)
Paxos分析 最近研究paxos算法,看了许多相关的文章,概念还是很模糊,觉得还是没有掌握paxos算法的精髓,所以花了3天时间分析了libpaxos3的所有代码,此代码可以从https://bit ...
- 记录一下寄几个儿的greendao数据库升级,可以说是非常菜鸡了嗯
之前使用的greendao数据库存储服务器所有的历史推送消息,但是后来消息需要加几个新的字段 举个栗子,比如要新增红色框住的字段到数据库中: 本仙女作为一只思想成熟的菜鸡,当然是加了字段就赶紧重新往里 ...
- 【原创】在VS2012中采用C++中调用DLL中的函数(4)
这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人 ...
- MYSQL查询前30条数据
, LIMIT 接受一个或两个数字参数. 参数必须是一个整数常量. 如果给定两个参数,第一个参数指定第一个返回记录行的偏移量, 第二个参数指定返回记录行的最大数目. 初始记录行的偏移量是 (而不是 )
- 从LeNet到SENet——卷积神经网络回顾
从LeNet到SENet——卷积神经网络回顾 从 1998 年经典的 LeNet,到 2012 年历史性的 AlexNet,之后深度学习进入了蓬勃发展阶段,百花齐放,大放异彩,出现了各式各样的不同网络 ...
- python numpy的transpose函数用法
#MXNET的N*C*H*W在numpy打印时比较直观#mxnet卷积层# 输入数据格式是:batch * inchannel * height * width# 输出数据格式是:batch * ou ...
- C艹函数与结构体
传递指针 代码: #include <iostream> #include <cmath> struct polar{ double distance; double angl ...
- (笔记)Mysql实例:建库建表并插入数据1
drop database if exists school; // 如果存在school则删除create database school; // 建立库schooluse school; / ...