1.分析这行代码:
ApplicationContext beanFactory = new ClassPathXmlApplicationContext(“spring/springmvc.xml”);
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
// 直接调用重载的方法
this(new String[]{configLocation}, true, (ApplicationContext)null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
//存储Springmvc.xml 路径 具体看1.1
this.setConfigLocations(configLocations);
if (refresh) {
// 初始化的时候refresh==true,核心逻辑的开始 具体看1.2
this.refresh();
}
}
1.1 存储xml文件路径。
// AbstractRefreshableConfigApplicationContext 类
public void setConfigLocations(String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for(int i = 0; i < locations.length; ++i) {
// 把xml路径放入到 String[] configLocations 中,支持多个配置文件以数组方式同时传入。
this.configLocations[i] = this.resolvePath(locations[i]).trim();
}
} else {
this.configLocations = null;
}
}
1.2 refresh()方法 在AbstractApplicationContext类中
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
// 准备刷新上下文环境 具体看 1.3
this.prepareRefresh();
/*
加载BeanFactory,ApplicationContext是对BeanFactory功能的扩展,这个方法就是用来获取BeanFactory
具体看 1.4
*/
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
1.3 环境准备
// 实际这一段并没有做任何事,主要是为了扩展用的,spring本身并没有做任何事情
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (this.logger.isInfoEnabled()) {
this.logger.info("Refreshing " + this);
}
// 留给子类覆盖
this.initPropertySources();
// 验证需要的属性文件是否都已经放入环境中
this.getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet();
}
1.4 obtainFreshBeanFactory()具体实现 AbstractApplicationContext类
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 调用相同类下的 refreshBeanFactory()方法 具体看 1.4.1
this.refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
1.4.1 refreshBeanFanctory() 在 AbstractRefreshableApplicationContext类中
protected final void refreshBeanFactory() throws BeansException {
// 判断是否有BeanFactory,初始化的时候,是没有的,false
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
// 创建DefaultListableBeanFactory,
// new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
beanFactory.setSerializationId(this.getId());
// 定制BeanFactory 具体看1.4.1.1
this.customizeBeanFactory(beanFactory);
// 初始化 DocumetReader ,并进行XML文件读取及解析 具体看1.4.1.2
this.loadBeanDefinitions(beanFactory);
Object var2 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
1.4.1.1 定制化BeanFactory ,对BeanFactory进行功能扩展
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding.booleanValue());
}
// 是否允许bean之间存在循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences.booleanValue());
}
}
1.4.1.2 初始化 DocumetReader ,并进行XML文件读取及解析 在AbstractXmlApplicationContext类
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 初始化BeanFactoryReader ,实际上就是加如一个验证位
this.initBeanDefinitionReader(beanDefinitionReader);
// 这里XmlBeanFactory创建时一样,通过一个XmlBeanDefinitionReader来读取Xml
this.loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// 检查ClassPathXmlApplicationContext中的 Resource[] configResources; 是否有资源,有就加载。
Resource[] configResources = this.getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
/*
检查AbstractRefreshableConfigApplicationContext中的String[] configLocations 中是否有资源
前面在 this.setConfigLocations(configLocations); 中我们把传入的 spring\mvc.xml 路径存入进去了。
*/
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
// 根据路径加载 BeanDefinition 到 DefaultListableBeanFactory中去了,
// 具体实现参考 XmlBeanFactory的初始化
reader.loadBeanDefinitions(configLocations);
}
}
至此,ApplicationContext中已经具有了XmlBeanFactory的功能。
即已经完成XmlBeanFactory的初始化,接下来看扩展。
2. 功能扩展 回到refresh()方法
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
// 准备刷新上下文环境 具体看 1.3
this.prepareRefresh();
/*
加载BeanFactory,ApplicationContext是对BeanFactory功能的扩展,这个方法就是用来获取BeanFactory
具体看 1.4
*/
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 在这之前,已经完成了对配置的解析。 ApplicationContext的功能扩展正式展开。
// prepareBeanFactory 具体看 2.1
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册beanFactory 中所有的BeanPostProcessor ,在前面prepareBeanFactory方法中,添加了几个
// BeanPostProcessor ,但那里只是实现了,并添加。还没有注册,在这里进行注册。
// 具体 看 2.2
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
// 注册监听器 监听器利用了观察者模式,ApplicationCotext中注册观测者(监听器)
this.registerListeners();
// 初始化非延迟加载 这个是重点的重点 具体分析看 2.3
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
2.1 prepareBeanFactory() 在 AbstractApplicationContext
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置beanFactory的classLoader为当前context的classLoader
beanFactory.setBeanClassLoader(this.getClassLoader());
// 设置beanFactory的表达式语言
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
/*
增加对属性编辑器的支持,例如在SpringDI注入的时候,可以把普通属性注入进来,但是像Date类型就无法识别,
就需要这个转换了,不过一般时间
*/
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
// 添加BeanPostProcessor ,添加ApplicationContextAwareProcessor处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 设置几个忽略自动装配的接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 可以看到有很多addBeanPostProcessor,那这个到底是什么呢? 具体看 2.1.1
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 增加对AspectJ的支持
if (beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 添加默认的系统环境bean
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
}
2.1.1 BeanPostProcessor 接口
/*
从这个接口看,有两个方法,bean初始化前调用的方法,bean初始化后调用的方法。
每一个实现的BeanPostProcessor接口的类,都能在bean初始化前后,实现一些逻辑。
所以,Spring中大部分功能都是通过后处理器的方式进行扩展的。
*/
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}
2.2 注册BeanPostProcessor
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 使用priorityOrderedPostProcessors 保证顺序。
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<BeanPostProcessor> internalPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
List<String> nonOrderedPostProcessorNames = new ArrayList();
String[] var8 = postProcessorNames;
int var9 = postProcessorNames.length;
String ppName;
BeanPostProcessor pp;
for(int var10 = 0; var10 < var9; ++var10) {
ppName = var8[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();
while(var14.hasNext()) {
String ppName = (String)var14.next();
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(beanFactory, orderedPostProcessors);
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();
while(var17.hasNext()) {
ppName = (String)var17.next();
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
sortPostProcessors(beanFactory, internalPostProcessors);
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
2.3 初始化非延迟加载
都知道ApplicationContext相对于XmlBeanFactory的区别就在于ApplicationContext会在初始化容器的时候,把bean顺带也加载了,而XmlBeanFactory不会,只有用到的时候才会加载。 具体来分析这个方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
public String resolveStringValue(String strVal) {
return AbstractApplicationContext.this.getEnvironment().resolvePlaceholders(strVal);
}
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
// 核心初始化方法
beanFactory.preInstantiateSingletons();
}
// 实际加载bean的方法, 在 DefaulistableBeanFactory中。 这里和XmlBeanFactory一样,
// 通过getBean(beanName) 来实例化bean。
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// 获取beanDefinitionNames 中 所有的beanName,为初始化准备
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
.....
// 如果是FactoryBean,那就得到这个对象。
if (this.isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean)this.getBean("&" + beanName);
boolean isEagerInit;
...... // 这其中都是一堆的判断
if (isEagerInit) {
this.getBean(beanName);
}
} else {
// 前面都是各种判断,这里才是真正的实例化bean 的地方。
this.getBean(beanName);
}
}
}
}
2.4 getBean的逻辑加载
Bean的生命周期:
在实例化前后会有两个切面
在初始化前后会有两个切面
AbstractBeanFactory.doGetBean
其中逻辑太过复杂,就不写了,
主要就是:
1. 调用getBean
2. 判断是否可以实例化,(是单例对象,不是抽象类型,不是LazyInit) 是
3. 是否是FactoryBean 否
4. 查询singletonObject(一级缓存)中是否存在 否
5. 是否有父工厂
- 是 获取其父工厂调用getBean
- 否 下一步
6. 检查Bean对象是否有依赖关系
- 有 获取所依赖的Bean对象
- 这里有一个解决循环依赖的问题,会通过提前曝光实例,通过三级缓存来解决。
- 否 下一步
7. 检查Bean对象是什么类型
- 是single 调用自动装配工厂产生Bean对象实例。
- 是Prototype 创建Bean对象实例。
8.返回bean对象实例,并将其存入到一级缓存。