Spring5源码
# Spring5源码
# 1、SpringIOC源码解析
先分析Spring的IOC模块的整体流程,分析过程需要使用一个简单的demo工程来启动Spring
Demo工程示例代码
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.0.RELEASE</version> </dependency> </dependencies>
1
2
3
4
5
6
7写一个简单的接口和实现类
public interface IOCService { public String hollo(); } public class IOCServiceImpl implements IOCService { public String hollo() { return "Hello,IOC"; } }
1
2
3
4
5
6
7
8
9新建application-ioc.xml
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName"> <bean id="iocservice" class="cn.shiyujun.service.impl.IOCServiceImpl"/> </beans>
1
2
3
4
5
6
7启动Spring
public class IOCDemo { public static void main (String args[]){ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-ioc.xml"); IOCService iocService=context.getBean(IOCService.class); System.out.println(iocService.hollo()); } }
1
2
3
4
5
6
7
看源码
# 1.1、ClassPathXmlApplicationContext
先看一下源码
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext { //配置文件数组 @Nullable private Resource[] configResources; public ClassPathXmlApplicationContext() { } // 指定ApplicationContext的父容器 public ClassPathXmlApplicationContext(ApplicationContext parent) { super(parent); } public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[]{configLocation}, true, (ApplicationContext)null); } public ClassPathXmlApplicationContext(String... configLocations) throws BeansException { this(configLocations, true, (ApplicationContext)null); } public ClassPathXmlApplicationContext(String[] configLocations, @Nullable ApplicationContext parent) throws BeansException { this(configLocations, true, parent); } public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException { this(configLocations, refresh, (ApplicationContext)null); } public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); // 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割) this.setConfigLocations(configLocations); if (refresh) { this.refresh(); } } public ClassPathXmlApplicationContext(String path, Class<?> clazz) throws BeansException { this(new String[]{path}, clazz); } public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz) throws BeansException { this(paths, clazz, (ApplicationContext)null); } public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, @Nullable ApplicationContext parent) throws BeansException { super(parent); Assert.notNull(paths, "Path array must not be null"); Assert.notNull(clazz, "Class argument must not be null"); this.configResources = new Resource[paths.length]; for(int i = 0; i < paths.length; ++i) { this.configResources[i] = new ClassPathResource(paths[i], clazz); } this.refresh(); } @Nullable protected Resource[] getConfigResources() { return this.configResources; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 1.1.1 、setConfigLocations
setConfigLocations方法的主要工作有两个:创建环境对象ConfigurableEnvironment和处理ClassPathXmlApplicationContext传入的字符串中的占位符
setConfigLocations源码:
public void setConfigLocations(@Nullable 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) { this.configLocations[i] = this.resolvePath(locations[i]).trim(); } } else { this.configLocations = null; } }
1
2
3
4
5
6
7
8
9
10
11
12
13resolvePath方法内部代码:
protected String resolvePath(String path) { return this.getEnvironment().resolveRequiredPlaceholders(path); }
1
2
3getEnvironment方法是创建环境变量
public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = this.createEnvironment(); } return this.environment; }
1
2
3
4
5
6
7首先看一下ConfigurableEnvironment类的结构图
这个接口比较重要的就是这两部分内容了,一个是设置Spring的环境就是我们经常使用的spring.profile配置,另一个就是系统资源Property
接着看createEnvironment方法,会返回一个StandardEnvironment对象
protected ConfigurableEnvironment createEnvironment() { return new StandardEnvironment(); } //StandardEnvironment类 public class StandardEnvironment extends AbstractEnvironment { public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment"; public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties"; public StandardEnvironment() { } protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new MapPropertySource("systemProperties", this.getSystemProperties())); propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", this.getSystemEnvironment())); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16其中的customizePropertySources方法会往资源列表中添加Java进程中的变量和系统的环境变量
处理占位符
再次回到resolvePath方法后,跟进resolveRequiredPlaceholders方法,最终进行逻辑处理的是parseStringValue方法,这个方法主要就是处理所有使用${}方式的占位符
protected String parseStringValue(String value, PropertyPlaceholderHelper.PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
StringBuilder result = new StringBuilder(value);
int startIndex = value.indexOf(this.placeholderPrefix);
while(startIndex != -1) {
int endIndex = this.findPlaceholderEndIndex(result, startIndex);
if (endIndex != -1) {
String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
String originalPlaceholder = placeholder;
if (!visitedPlaceholders.add(placeholder)) {
throw new IllegalArgumentException("Circular placeholder reference '" + placeholder + "' in property definitions");
}
placeholder = this.parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
String propVal = placeholderResolver.resolvePlaceholder(placeholder);
if (propVal == null && this.valueSeparator != null) {
int separatorIndex = placeholder.indexOf(this.valueSeparator);
if (separatorIndex != -1) {
String actualPlaceholder = placeholder.substring(0, separatorIndex);
String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
if (propVal == null) {
propVal = defaultValue;
}
}
}
if (propVal != null) {
propVal = this.parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
if (logger.isTraceEnabled()) {
logger.trace("Resolved placeholder '" + placeholder + "'");
}
startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
} else {
if (!this.ignoreUnresolvablePlaceholders) {
throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "' in value \"" + value + "\"");
}
startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
}
visitedPlaceholders.remove(originalPlaceholder);
} else {
startIndex = -1;
}
}
return result.toString();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 1.1.2、refresh
配置文件名称解析完毕后,就到了最关键的一步refresh方法
先看一下这个方法的大致内容:
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
//做一些准备工作,记录容器的启动时间、标记“已启动”状态、检查环境变量等
this.prepareRefresh();
//负责了BeanFactory的初始化、Bean的加载和注册等事件
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//会设置BeanFactory的类加载器、添加几个 BeanPostProcessor、手动注册几个特殊的bean
this.prepareBeanFactory(beanFactory);
try {
//Spring的一个扩展点
this.postProcessBeanFactory(beanFactory);
//调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory(factory) 方法
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类
this.registerBeanPostProcessors(beanFactory);
// 初始化MessageSource
this.initMessageSource();
//初始化当前 ApplicationContext 的事件广播器
this.initApplicationEventMulticaster();
// 扩展点
this.onRefresh();
// 注册事件监听器
this.registerListeners();
//初始化所有的 singleton beans
this.finishBeanFactoryInitialization(beanFactory);
// 广播事件
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
// 销毁已经初始化的的Bean
this.destroyBeans();
// 设置 'active' 状态
this.cancelRefresh(var9);
throw var9;
} finally {
// 清除缓存
this.resetCommonCaches();
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
开始分析:
# 1.1.2.1、synchronized
为了避免
refresh()
还没结束,再次发起启动或者销毁容器引起的冲突
# 1.1.2.2、prepareRefresh()
做一些准备工作,记录容器的启动时间、标记“已启动”状态、检查环境变量等
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
2
3
4
5
6
7
8
9
10
11
12
13其中检查环境变量的核心方法为,简单来说就是如果存在环境变量的value
为空的时候就抛异常,然后停止启动Spring
public void validateRequiredProperties() { MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException(); Iterator var2 = this.requiredProperties.iterator(); while(var2.hasNext()) { String key = (String)var2.next(); if (this.getProperty(key) == null) { ex.addMissingRequiredProperty(key); } } if (!ex.getMissingRequiredProperties().isEmpty()) { throw ex; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15基于这个特性我们可以做一些扩展,提前在集合
requiredProperties
中放入我们这个项目必须存在的一些环境变量。假说我们的生产环境数据库地址、用户名和密码都是使用环境变量的方式注入进去来代替测试环境的配置,那么就可以在这里添加这个校验,在程序刚启动的时候就能发现问题
# 1.1.2.3、obtainFreshBeanFactory
负责了BeanFactory的初始化、Bean的加载和注册等事件
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 核心 this.refreshBeanFactory(); // 返回刚刚创建的 BeanFactory ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); if (this.logger.isDebugEnabled()) { this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory); } return beanFactory; }
1
2
3
4
5
6
7
8
9
10
11先看refreshBeanFactory
protected final void refreshBeanFactory() throws BeansException { // 判断当前ApplicationContext是否存在BeanFactory,如果存在的话就销毁所有 Bean,关闭 BeanFactory // 注意,一个应用可以存在多个BeanFactory,这里判断的是当前ApplicationContext是否存在BeanFactory if (this.hasBeanFactory()) { this.destroyBeans(); this.closeBeanFactory(); } try { // 初始化DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = this.createBeanFactory(); beanFactory.setSerializationId(this.getId()); // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用 this.customizeBeanFactory(beanFactory); // 加载 Bean 到 BeanFactory 中 this.loadBeanDefinitions(beanFactory); synchronized(this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException var5) { throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23先看一下类图
loadBeanDefinitions:看这个方法之前,先了解BeanDefinition这个类
我们知道BeanFactory是一个Bean容器,而BeanDefinition就是Bean的一种形式(它里面包含了Bean指向的类、是否单例、是否懒加载、Bean的依赖关系等相关的属性)。BeanFactory中就是保存的BeanDefinition
看BeanDefinition的接口定义:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { // Bean的生命周期,默认只提供sington和prototype两种,在WebApplicationContext中还会有request, session, globalSession, application, websocket 等 String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype"; int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; // 设置父Bean void setParentName(@Nullable String var1); // 获取父Bean @Nullable String getParentName(); // 设置Bean的类名称 void setBeanClassName(@Nullable String var1); // 获取Bean的类名称 @Nullable String getBeanClassName(); // 设置bean的scope void setScope(@Nullable String var1); @Nullable String getScope(); // 设置是否懒加载 void setLazyInit(boolean var1); boolean isLazyInit(); // 设置该Bean依赖的所有Bean void setDependsOn(@Nullable String... var1); // 返回该Bean的所有依赖 @Nullable String[] getDependsOn(); // 设置该Bean是否可以注入到其他Bean中 void setAutowireCandidate(boolean var1); // 该Bean是否可以注入到其他Bean中 boolean isAutowireCandidate(); // 同一接口的多个实现,如果不指定名字的话,Spring会优先选择设置primary为true的bean void setPrimary(boolean var1); // 是否是primary的 boolean isPrimary(); // 指定工厂名称 void setFactoryBeanName(@Nullable String var1); // 获取工厂名称 @Nullable String getFactoryBeanName(); // 指定工厂类中的工厂方法名称 void setFactoryMethodName(@Nullable String var1); // 获取工厂类中的工厂方法名称 @Nullable String getFactoryMethodName(); // 构造器参数 ConstructorArgumentValues getConstructorArgumentValues(); default boolean hasConstructorArgumentValues() { return !this.getConstructorArgumentValues().isEmpty(); } // Bean 中的属性值,后面给 bean 注入属性值的时候会说到 MutablePropertyValues getPropertyValues(); default boolean hasPropertyValues() { return !this.getPropertyValues().isEmpty(); } // 是否 singleton boolean isSingleton(); // 是否 prototype boolean isPrototype(); // 如果这个 Bean 是被设置为 abstract,那么不能实例化,常用于作为 父bean 用于继承 boolean isAbstract(); int getRole(); @Nullable String getDescription(); @Nullable String getResourceDescription(); @Nullable BeanDefinition getOriginatingBeanDefinition(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101现在可以看
loadBeanDefinitions()
方法了,这个方法会根据配置,加载各个 Bean,然后放到 BeanFactory 中protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // 实例化XmlBeanDefinitionReader XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // 初始化 BeanDefinitionReader this.initBeanDefinitionReader(beanDefinitionReader); this.loadBeanDefinitions(beanDefinitionReader); } protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { //系统指定的配置文件 Resource[] configResources = this.getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } //代码中传递的配置文件 String[] configLocations = this.getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24第一个if是看有没有系统指定的配置文件,如果没有的话就走第二个if加载我们最开始传入的
classpath:application-ioc.xml
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException { Assert.notNull(locations, "Location array must not be null"); int counter = 0; String[] var3 = locations; int var4 = locations.length; for(int var5 = 0; var5 < var4; ++var5) { String location = var3[var5]; counter += this.loadBeanDefinitions(location); } // 最后返回加载的所有BeanDefinition的数量 return counter; } public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { return this.loadBeanDefinitions(location, (Set)null); } public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException { ResourceLoader resourceLoader = this.getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available"); } else { int loadCount; if (!(resourceLoader instanceof ResourcePatternResolver)) { Resource resource = resourceLoader.getResource(location); loadCount = this.loadBeanDefinitions((Resource)resource); if (actualResources != null) { actualResources.add(resource); } if (this.logger.isDebugEnabled()) { this.logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); } return loadCount; } else { try { //将配置文件转换为Resource对象 Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location); loadCount = this.loadBeanDefinitions(resources); if (actualResources != null) { Resource[] var6 = resources; int var7 = resources.length; for(int var8 = 0; var8 < var7; ++var8) { Resource resource = var6[var8]; actualResources.add(resource); } } if (this.logger.isDebugEnabled()) { this.logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]"); } return loadCount; } catch (IOException var10) { throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var10); } } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60这里先小小的看一下Spring中的设计模式,我们跟着
loadBeanDefinitions()
方法往下走,最终会进入类XmlBeanDefinitionReader,这是因为我们这里要解析的配置文件是XML。如果我们使用Java类配置或者是Groovy的话就是另外的类了。看一下这个类继承图:继续分析:
XmlBeanDefinitionReader#loadBeanDefinitions()
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (this.logger.isInfoEnabled()) { this.logger.info("Loading XML bean definitions from " + encodedResource.getResource()); } Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!((Set)currentResources).add(encodedResource)) { throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } else { int var5; try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException var15) { throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15); } finally { ((Set)currentResources).remove(encodedResource); if (((Set)currentResources).isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } return var5; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42下面分为两步:
XmlBeanDefinitionReader#doLoadBeanDefinitions()
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { //将 xml 文件转换为 Document 对象 Document doc = this.doLoadDocument(inputSource, resource); //根据Document对象注册Bean return this.registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException var4) { throw var4; } catch (SAXParseException var5) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var5.getLineNumber() + " in XML document from " + resource + " is invalid", var5); } catch (SAXException var6) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var6); } catch (ParserConfigurationException var7) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var7); } catch (IOException var8) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var8); } catch (Throwable var9) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var9); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20分析注册Bean:
XmlBeanDefinitionReader#registerBeanDefinitions()
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //构建读取Document的工具类 BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader(); //获取已注册的bean数量 int countBefore = this.getRegistry().getBeanDefinitionCount(); // 在这接着往下看 documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource)); //总注册的bean减去之前注册的bean就是本次注册的bean return this.getRegistry().getBeanDefinitionCount() - countBefore; } public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; this.logger.debug("Loading bean definitions"); //获取Document的根节点 Element root = doc.getDocumentElement(); //继续往下 this.doRegisterBeanDefinitions(root); } protected void doRegisterBeanDefinitions(Element root) { // 当前根节点 BeanDefinitionParserDelegate parent = this.delegate; this.delegate = this.createDelegate(this.getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { // 获取 <beans ... profile="***" /> 中的 profile参数与当前环境是否匹配,如果不匹配则不再进行解析 String profileSpec = root.getAttribute("profile"); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; "); if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (this.logger.isInfoEnabled()) { this.logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource()); } return; } } } // 前置扩展点 this.preProcessXml(root); // 往下看 this.parseBeanDefinitions(root, this.delegate); // 后置扩展点 this.postProcessXml(root); this.delegate = parent; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45改变bean定义的扩展点:preProcessXml和postProcessXml着两个办法是留给我们实现DefaultBeanDefinitionDocumentReader方法后自定义实现的(后续再看)
看核心解析方法
parseBeanDefinitions()
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { // default namespace 涉及到的就四个标签 <import />、<alias />、<bean /> 和 <beans /> if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for(int i = 0; i < nl.getLength(); ++i) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element)node; if (delegate.isDefaultNamespace(ele)) { // 解析 default namespace 下面的几个元素 this.parseDefaultElement(ele, delegate); } else { // 解析其他 namespace 的元素 delegate.parseCustomElement(ele); } } } } else { // 解析其他 namespace 的元素 delegate.parseCustomElement(root); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23default标签处理:
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, "import")) { // 处理 <import /> 标签 this.importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, "alias")) { // 处理 <alias /> 标签 // <alias name="fromName" alias="toName"/> this.processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, "bean")) { // 处理 <bean /> 标签定义 this.processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, "beans")) { // 处理 <beans /> 标签 this.doRegisterBeanDefinitions(ele); } } //简单看一下<bean /> 标签的处理方式: protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //创建BeanDefinition BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { // 如果有自定义属性的话,进行相应的解析 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // 注册Bean BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException var5) { this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5); } // 注册完成后,发送事件 this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
341、先从第一行看:delegate.parseBeanDefinitionElement(ele)
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { return this.parseBeanDefinitionElement(ele, (BeanDefinition)null); } public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) { String id = ele.getAttribute("id"); String nameAttr = ele.getAttribute("name"); List<String> aliases = new ArrayList(); // 将 name 属性的定义按照 “逗号、分号、空格” 切分,形成一个 别名列表数组, if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; "); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; // 如果没有指定id, 那么用别名列表的第一个名字作为beanName if (!StringUtils.hasText(id) && !aliases.isEmpty()) { beanName = (String)aliases.remove(0); if (this.logger.isDebugEnabled()) { this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } if (containingBean == null) { this.checkNameUniqueness(beanName, aliases, ele); } // 根据 <bean ...>...</bean> 中的配置创建 BeanDefinition,然后把配置中的信息都设置到实例中, // 这行执行完毕,一个 BeanDefinition 实例就出来了。等下接着往下看 AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean); // <bean /> 标签完成 if (beanDefinition != null) { // 如果没有设置 id 和 name,那么此时的 beanName 就会为 null if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true); } else { beanName = this.readerContext.generateBeanName(beanDefinition); String beanClassName = beanDefinition.getBeanClassName(); if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { // 把 beanClassName 设置为 Bean 的别名 aliases.add(beanClassName); } } if (this.logger.isDebugEnabled()) { this.logger.debug("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]"); } } catch (Exception var9) { this.error(var9.getMessage(), ele); return null; } } String[] aliasesArray = StringUtils.toStringArray(aliases); // 返回 BeanDefinitionHolder return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } else { return null; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62创建BeanDefinition 接着是最重要的地方,如何根据配置创建 BeanDefinition 实例: this.parseBeanDefinitionElement
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); String className = null; if (ele.hasAttribute("class")) { className = ele.getAttribute("class").trim(); } String parent = null; if (ele.hasAttribute("parent")) { parent = ele.getAttribute("parent"); } try { // 创建 BeanDefinition,然后设置类信息 AbstractBeanDefinition bd = this.createBeanDefinition(className, parent); // 设置 BeanDefinition 的一堆属性,这些属性定义在 AbstractBeanDefinition 中 this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description")); /** * 下面的一堆是解析 <bean>......</bean> 内部的子元素, * 解析出来以后的信息都放到 bd 的属性中 */ // 解析 <meta /> this.parseMetaElements(ele, bd); // 解析 <lookup-method /> this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); // 解析 <replaced-method /> this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); // 解析 <constructor-arg /> this.parseConstructorArgElements(ele, bd); // 解析 <property /> this.parsePropertyElements(ele, bd); // 解析 <qualifier /> this.parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(this.extractSource(ele)); AbstractBeanDefinition var7 = bd; return var7; } catch (ClassNotFoundException var13) { this.error("Bean class [" + className + "] not found", ele, var13); } catch (NoClassDefFoundError var14) { this.error("Class that bean class [" + className + "] depends on not found", ele, var14); } catch (Throwable var15) { this.error("Unexpected failure during bean definition parsing", ele, var15); } finally { this.parseState.pop(); } return null; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
532、接着回到刚才的代码:开始看注册Bean
BeanDefinitionReaderUtils.registerBeanDefinition();
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { String beanName = definitionHolder.getBeanName(); // 注册这个 Bean registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); String[] aliases = definitionHolder.getAliases(); // 如果配置有别名的话,也要根据别名全部注册一遍 if (aliases != null) { String[] var4 = aliases; int var5 = aliases.length; for(int var6 = 0; var6 < var5; ++var6) { String alias = var4[var6]; registry.registerAlias(beanName, alias); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16具体的注册方法 registry.registerBeanDefinition()
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition)beanDefinition).validate(); } catch (BeanDefinitionValidationException var9) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9); } } // 所有的 Bean 注册后都会被放入到这个beanDefinitionMap 中,查看是否已存在这个bean BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { // 如果不允许覆盖的话,抛异常 if (!this.isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // 用框架定义的 Bean 覆盖用户自定义的 Bean if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { // 用新的 Bean 覆盖旧的 Bean if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (this.logger.isDebugEnabled()) { // log...用同等的 Bean 覆盖旧的 Bean this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } // 覆盖 this.beanDefinitionMap.put(beanName, beanDefinition); } else { // 判断是否已经有其他的 Bean 开始初始化了.注意,"注册Bean" 这个动作结束,Bean 依然还没有初始化 在 Spring 容器启动的最后,会 预初始化 所有的 singleton beans if (this.hasBeanCreationStarted()) { synchronized(this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // 将 BeanDefinition 放到这个 map 中,这个 map 保存了所有的 BeanDefinition this.beanDefinitionMap.put(beanName, beanDefinition); // 这是个 ArrayList,所以会按照 bean 配置的顺序保存每一个注册的 Bean 的名字 this.beanDefinitionNames.add(beanName); // 这是个 LinkedHashSet,代表的是手动注册的 singleton bean this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || this.containsSingleton(beanName)) { this.resetBeanDefinition(beanName); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68到这里已经初始化了 Bean 容器,
的配置也相应的转换为了一个个BeanDefinition,然后注册了所有的BeanDefinition到beanDefinitionMap
# 1.1.2.4 、prepareBeanFactory()
prepareBeanFactory()
这个方法主要会设置BeanFactory的类加载器、添加几个 BeanPostProcessor、手动注册几个特殊的beanprotected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 设置为加载当前ApplicationContext类的类加载器 beanFactory.setBeanClassLoader(this.getClassLoader()); // 设置 BeanExpressionResolver beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment())); // 这里是Spring的又一个扩展点 //在所有实现了Aware接口的bean在初始化的时候,这个 processor负责回调, // 这个我们很常用,如我们会为了获取 ApplicationContext 而 implement ApplicationContextAware // 注意:它不仅仅回调 ApplicationContextAware,还会负责回调 EnvironmentAware、ResourceLoaderAware 等 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 下面几行的意思就是,如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,Spring 会通过其他方式来处理这些依赖。 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //下面几行就是为特殊的几个 bean 赋值,如果有 bean 依赖了以下几个,会注入这边相应的值 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 注册 事件监听器 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 如果存在bean名称为loadTimeWeaver的bean则注册一个BeanPostProcessor if (beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 如果没有定义 "environment" 这个 bean,那么 Spring 会 "手动" 注册一个 if (!beanFactory.containsLocalBean("environment")) { beanFactory.registerSingleton("environment", this.getEnvironment()); } // 如果没有定义 "systemProperties" 这个 bean,那么 Spring 会 "手动" 注册一个 if (!beanFactory.containsLocalBean("systemProperties")) { beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties()); } // 如果没有定义 "systemEnvironment" 这个 bean,那么 Spring 会 "手动" 注册一个 if (!beanFactory.containsLocalBean("systemEnvironment")) { beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment()); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 1.1.2.5 、postProcessBeanFactory()
如果有Bean实现了BeanFactoryPostProcessor接口,那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
# 1.1.2.6 、invokeBeanFactoryPostProcessors()
调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory(factory) 方法
# 1.1.2.7、registerBeanPostProcessors()
Spring的一个扩展点
注册 BeanPostProcessor 的实现类,注意不是BeanFactoryPostProcessor
此接口有两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization分别会在Bean初始化之前和初始化之后得到执行
# 1.1.2.8、initMessageSource
初始化当前 ApplicationContext 的 MessageSource,有想了解国际化的相关知识可以深入研究一下
# 1.1.2.9、initApplicationEventMulticaster()
这个方法主要为初始化当前 ApplicationContext 的事件广播器
protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); //如果用户配置了自定义事件广播器,就使用用户的 if (beanFactory.containsLocalBean("applicationEventMulticaster")) { this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class); if (this.logger.isDebugEnabled()) { this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { //使用默认的事件广播器 this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster); if (this.logger.isDebugEnabled()) { this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]"); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1.1.2.10、onRefresh()
一个扩展点,子类可以在这里来搞事情 (
Springboot在这个扩展中启动服务器
)
# 1.1.2.11 、registerListeners()
注册事件监听器
protected void registerListeners() { Iterator var1 = this.getApplicationListeners().iterator(); //先添加手动set的一些监听器 while(var1.hasNext()) { ApplicationListener<?> listener = (ApplicationListener)var1.next(); this.getApplicationEventMulticaster().addApplicationListener(listener); } //取到监听器的名称,设置到广播器 String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false); String[] var7 = listenerBeanNames; int var3 = listenerBeanNames.length; for(int var4 = 0; var4 < var3; ++var4) { String listenerBeanName = var7[var4]; this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 如果存在早期应用事件,发布 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { Iterator var9 = earlyEventsToProcess.iterator(); while(var9.hasNext()) { ApplicationEvent earlyEvent = (ApplicationEvent)var9.next(); this.getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 1.1.2.12、finishBeanFactoryInitialization
刚才我们提到了bean还没有初始化。这个方法就是负责初始化所有的没有设置懒加载的singleton bean
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((strVal) -> { return this.getEnvironment().resolvePlaceholders(strVal); }); } //先初始化 LoadTimeWeaverAware 类型的 Bean 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); //冻结所有的bean定义,即已注册的bean定义将不会被修改或后处理 beanFactory.freezeConfiguration(); //初始化 beanFactory.preInstantiateSingletons(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
261、conversionService:
这种类型的bean最实用的场景就是用来将前端传过来的参数和后端的controller方法上的参数格式转换的时候使用
例如:前端要传一个String,后端使用Date接受的时候就可以这样操作
public class StringToDateConverter implements Converter<String, Date> { @Override public Date convert(String date) { try { return dateFormat.parse(date); } catch (Exception e) { e.printStackTrace(); System.out.println("日期转换失败!"); return null; } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14再配置一个bean
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="cn.shiyujun.utils.StringToDateConverter"/> </list> </property> </bean>
1
2
3
4
5
6
7
82、EmbeddedValueResolver
利用EmbeddedValueResolver可以很方便的实现读取配置文件的属性
@Component public class PropertiesUtil implements EmbeddedValueResolverAware { private StringValueResolver resolver; @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { this.resolver = resolver; } /** * 获取属性时直接传入属性名称即可 */ public String getPropertiesValue(String key) { StringBuilder name = new StringBuilder("${").append(key).append("}"); return resolver.resolveStringValue(name.toString()); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
203、***
初始化: beanFactory.preInstantiateSingletons()
***public void preInstantiateSingletons() throws BeansException { if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } // this.beanDefinitionNames 保存了所有的 beanNames List<String> beanNames = new ArrayList(this.beanDefinitionNames); Iterator var2 = beanNames.iterator(); while(true) { String beanName; Object bean; do { while(true) { RootBeanDefinition bd; do { do { do { if (!var2.hasNext()) { var2 = beanNames.iterator(); while(var2.hasNext()) { beanName = (String)var2.next(); Object singletonInstance = this.getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged(() -> { smartSingleton.afterSingletonsInstantiated(); return null; }, this.getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } return; } beanName = (String)var2.next(); // 合并父 Bean 中的配置,<bean id="" class="" parent="" /> 中的 parent属性 bd = this.getMergedLocalBeanDefinition(beanName); } while(bd.isAbstract()); } while(!bd.isSingleton()); } while(bd.isLazyInit()); //三个while / 不是抽象类、是单例的且不是懒加载的 // 处理 FactoryBean if (this.isFactoryBean(beanName)) { //在 beanName 前面加上“&” 符号 bean = this.getBean("&" + beanName); break; } // 不是FactoryBean的直接使用此方法进行初始化 this.getBean(beanName); } } while(!(bean instanceof FactoryBean)); FactoryBean<?> factory = (FactoryBean)bean; boolean isEagerInit; // 判断当前 FactoryBean 是否是 SmartFactoryBean 的实现 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { SmartFactoryBean var10000 = (SmartFactoryBean)factory; ((SmartFactoryBean)factory).getClass(); isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext()); } else { isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit(); } if (isEagerInit) { this.getBean(beanName); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76getBean方法解析 : this.getBean(beanName);
public Object getBean(String name) throws BeansException { return this.doGetBean(name, (Class)null, (Object[])null, false); } protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { // 获取beanName,处理两种情况,一个是前面说的 FactoryBean(前面带 ‘&’),再一个这个方法是可以根据别名来获取Bean的,所以在这里是要转换成最正统的BeanName //主要逻辑就是如果是FactoryBean就把&去掉如果是别名就把根据别名获取真实名称后面就不贴代码了 String beanName = this.transformedBeanName(name); // 检查是否已初始化 Object sharedInstance = this.getSingleton(beanName); //最后的返回值 Object bean; //如果已经初始化过了,且没有传args参数就代表是get,直接取出返回 if (sharedInstance != null && args == null) { if (this.logger.isDebugEnabled()) { if (this.isSingletonCurrentlyInCreation(beanName)) { this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } // 这里如果是普通Bean 的话,直接返回,如果是 FactoryBean 的话,返回它创建的那个实例对象 bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); } else { // 如果存在prototype类型的这个bean if (this.isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 如果当前BeanDefinition不存在这个bean且具有父BeanFactory BeanFactory parentBeanFactory = this.getParentBeanFactory(); if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { String nameToLookup = this.originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } // 返回父容器的查询结果 if (args != null) { return parentBeanFactory.getBean(nameToLookup, args); } return parentBeanFactory.getBean(nameToLookup, requiredType); } // typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。 if (!typeCheckOnly) { this.markBeanAsCreated(beanName); } /* * 到这就要创建bean了 */ try { RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); this.checkMergedBeanDefinition(mbd, beanName, args); // 先初始化依赖的所有 Bean, depends-on 中定义的依赖 String[] dependsOn = mbd.getDependsOn(); String[] var11; if (dependsOn != null) { var11 = dependsOn; int var12 = dependsOn.length; for(int var13 = 0; var13 < var12; ++var13) { String dep = var11[var13]; // 检查是不是有循环依赖 if (this.isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } // 注册一下依赖关系 this.registerDependentBean(dep, beanName); // 先初始化被依赖项 this.getBean(dep); } } // 如果是单例的 if (mbd.isSingleton()) { sharedInstance = this.getSingleton(beanName, () -> { try { // 执行创建 Bean,下面说 return this.createBean(beanName, mbd, args); } catch (BeansException var5) { this.destroySingleton(beanName); throw var5; } }); bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // 如果是prototype var11 = null; Object prototypeInstance; try { this.beforePrototypeCreation(beanName); // 执行创建 Bean prototypeInstance = this.createBean(beanName, mbd, args); } finally { this.afterPrototypeCreation(beanName); } bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { // 如果不是 singleton 和 prototype 那么就是自定义的scope、例如Web项目中的session等类型,这里就交给自定义scope的应用方去实现 String scopeName = mbd.getScope(); Scope scope = (Scope)this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { this.beforePrototypeCreation(beanName); Object var4; try { var4 = this.createBean(beanName, mbd, args); } finally { this.afterPrototypeCreation(beanName); } return var4; }); bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException var21) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21); } } } catch (BeansException var23) { this.cleanupAfterBeanCreationFailure(beanName); throw var23; } } //检查bean的类型 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } else { return convertedBean; } } catch (TypeMismatchException var22) { if (this.logger.isDebugEnabled()) { this.logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var22); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } else { return bean; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156看了上方方法我们知道了原来Spring本身只定义了两种Scope,也知道了SpringMVC的几种Scope是如何实现的了。 然后发现一开始会先判断bean存不存在,如果存在就直接返回了。如果不存在那就要接着往下看
createBean
方法了protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (this.logger.isDebugEnabled()) { this.logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // 确保 BeanDefinition 中的 Class 被加载 Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // 准备方法覆写,如果bean中定义了 <lookup-method /> 和 <replaced-method /> try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException var10) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var10); } Object beanInstance; try { // 如果有代理的话直接返回 beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse); if (beanInstance != null) { return beanInstance; } } catch (Throwable var11) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var11); } try { // 创建 bean beanInstance = this.doCreateBean(beanName, mbdToUse, args); if (this.logger.isDebugEnabled()) { this.logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException var7) { throw var7; } catch (ImplicitlyAppearedSingletonException var8) { throw var8; } catch (Throwable var9) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var9); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
this.doCreateBean
方法解析:protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { //如果是factoryBean则从缓存删除 instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 实例化 Bean,这个方法里面才是重点,下面说 instanceWrapper = this.createBeanInstance(beanName, mbd, args); } //bean实例 Object bean = instanceWrapper.getWrappedInstance(); //bean类型 Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized(mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 循环调用实现了MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法 // Spring对这个接口有几个默认的实现,其中大家最熟悉的一个是操作@Autowired注解的 this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable var17) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17); } mbd.postProcessed = true; } } // 解决循环依赖问题 boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName); if (earlySingletonExposure) { if (this.logger.isDebugEnabled()) { this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } //当正在创建A时,A依赖B,此时通过(B将A作为ObjectFactory放入单例工厂中进行early expose,此处B需要引用A,但A正在创建,从单例工厂拿到ObjectFactory,从而允许循环依赖 this.addSingletonFactory(beanName, () -> { return this.getEarlyBeanReference(beanName, mbd, bean); }); } Object exposedObject = bean; try { // 负责属性装配,很重要,下面说 this.populateBean(beanName, mbd, instanceWrapper); // 这里是处理bean初始化完成后的各种回调,例如init-method、InitializingBean 接口、BeanPostProcessor 接口 exposedObject = this.initializeBean(beanName, exposedObject, mbd); } catch (Throwable var18) { if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) { throw (BeanCreationException)var18; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18); } //同样的,如果存在循环依赖 if (earlySingletonExposure) { Object earlySingletonReference = this.getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) { String[] dependentBeans = this.getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length); String[] var12 = dependentBeans; int var13 = dependentBeans.length; for(int var14 = 0; var14 < var13; ++var14) { String dependentBean = var12[var14]; if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // 把bean注册到相应的Scope中 try { this.registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; } catch (BeanDefinitionValidationException var16) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97创建bean实例
createBeanInstance ()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // 确保已经加载了此 class Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]); // 校验类的访问权限 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } else { Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return this.obtainFromSupplier(instanceSupplier, beanName); } else if (mbd.getFactoryMethodName() != null) { // 采用工厂方法实例化 return this.instantiateUsingFactoryMethod(beanName, mbd, args); } else { //是否第一次 boolean resolved = false; //是否采用构造函数注入 boolean autowireNecessary = false; if (args == null) { synchronized(mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd); } else { // 判断是否采用有参构造函数 Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName); return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args) ? //无参构造 this.instantiateBean(beanName, mbd) : //有参构造 this.autowireConstructor(beanName, mbd, ctors, args); } } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42this.instantiateBean 方法解析
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { try { Object beanInstance; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged(() -> { return thisx.getInstantiationStrategy().instantiate(mbd, beanName, this); }, this.getAccessControlContext()); } else { // 具体实例化的实现,往下看 beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); this.initBeanWrapper(bw); return bw; } catch (Throwable var6) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6); } } public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // 如果不存在方法覆写,那就使用 java 反射进行实例化,否则使用 CGLIB, if (!bd.hasMethodOverrides()) { Constructor constructorToUse; synchronized(bd.constructorArgumentLock) { constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { clazz.getClass(); constructorToUse = (Constructor)AccessController.doPrivileged(() -> { return clazz.getDeclaredConstructor(); }); } else { constructorToUse = clazz.getDeclaredConstructor(); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable var9) { throw new BeanInstantiationException(clazz, "No default constructor found", var9); } } } // 利用构造方法进行实例化 return BeanUtils.instantiateClass(constructorToUse, new Object[0]); } else { // 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类 return this.instantiateWithMethodInjection(bd, beanName, owner); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56bean属性注入
populateBean ()
this.populateBean(beanName, mbd, instanceWrapper); //填充Bean protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } } else { boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) { Iterator var5 = this.getBeanPostProcessors().iterator(); while(var5.hasNext()) { BeanPostProcessor bp = (BeanPostProcessor)var5.next(); if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (continueWithPropertyPopulation) { // bean的所有属性 PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null; if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) { MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs); // 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系 if (mbd.getResolvedAutowireMode() == 1) { this.autowireByName(beanName, mbd, bw, newPvs); } // 通过类型装配。复杂一些 if (mbd.getResolvedAutowireMode() == 2) { this.autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = mbd.getDependencyCheck() != 0; if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { Iterator var9 = this.getBeanPostProcessors().iterator(); while(var9.hasNext()) { BeanPostProcessor bp = (BeanPostProcessor)var9.next(); if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp; pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs); } } if (pvs != null) { // 设置 bean 实例的属性值 this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs); } } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 1.1.2.13、finishRefresh()
protected void finishRefresh() { //清理刚才一系列操作使用到的资源缓存 this.clearResourceCaches(); // 初始化LifecycleProcessor this.initLifecycleProcessor(); // 这个方法的内部实现是启动所有实现了Lifecycle接口的bean this.getLifecycleProcessor().onRefresh(); //发布ContextRefreshedEvent事件 this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this))); // 检查spring.liveBeansView.mbeanDomain是否存在,有就会创建一个MBeanServer LiveBeansView.registerApplicationContext(this); }
1
2
3
4
5
6
7
8
9
10
11
12
# 1.1.2.14、resetCommonCaches()
清除缓存
protected void resetCommonCaches() { ReflectionUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(this.getClassLoader()); }
1
2
3
4
5
# 1.2、AnnotationConfigApplicationContext
基于注解的IOC源码解析
# 1.2.1、构造方法
public AnnotationConfigApplicationContext(String... basePackages) { this(); this.scan(basePackages); this.refresh(); }
1
2
3
4
5
# 1.2.1.1 、this()
public AnnotationConfigApplicationContext() { //注解bean读取器 this.reader = new AnnotatedBeanDefinitionReader(this); //注解bean扫描器 this.scanner = new ClassPathBeanDefinitionScanner(this); }
1
2
3
4
5
6
同时子类的构造方法执行之前肯定会先执行父类的构造方法,所以还有父类GenericApplicationContext的构造方法
public GenericApplicationContext() {
this.customClassLoader = false;
this.refreshed = new AtomicBoolean();
this.beanFactory = new DefaultListableBeanFactory();
}
2
3
4
5
# 1.2.1.2 、scan(basePackages)
public void scan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); this.scanner.scan(basePackages); }
1
2
3
4可以看到这里调用的是bean扫描器
ClassPathBeanDefinitionScanner
的scan
方法public int scan(String... basePackages) { //获取当前注册bean的数量 int beanCountAtScanStart = this.registry.getBeanDefinitionCount(); //往下看,下面讲解 this.doScan(basePackages); if (this.includeAnnotationConfig) { //注册配置处理器 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } //返回此次注册的数量 return this.registry.getBeanDefinitionCount() - beanCountAtScanStart; } protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet(); String[] var3 = basePackages; int var4 = basePackages.length; //遍历需要扫描的包路径 for(int var5 = 0; var5 < var4; ++var5) { String basePackage = var3[var5]; //先跟进去看,下面的方法先忽略 扫描包 //获取所有符合条件的BeanDefinition Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage); Iterator var8 = candidates.iterator(); while(var8.hasNext()) { BeanDefinition candidate = (BeanDefinition)var8.next(); //绑定BeanDefinition与Scope ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); //查看是否配置类是否指定bean的名称,如没指定则使用类名首字母小写 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); //下面两个if是处理lazy、Autowire、DependencyOn、initMethod、enforceInitMethod、destroyMethod、enforceDestroyMethod、Primary、Role、Description这些逻辑的 if (candidate instanceof AbstractBeanDefinition) { this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate); } //检查bean是否存在 if (this.checkCandidate(beanName, candidate)) { //又包装了一层 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); //检查scope是否创建,如未创建则进行创建 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); //重点来了,往下看 this.registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
findCandidateComponents
方法解析:public Set<BeanDefinition> findCandidateComponents(String basePackage) { return this.componentsIndex != null && this.indexSupportsIncludeFilters() ? //判断是否使用Filter指定忽略包不扫描 this.addCandidateComponentsFromIndex(this.componentsIndex, basePackage) : //扫描包 this.scanCandidateComponents(basePackage); }
1
2
3
4
5
6
7先认识一个类,
MetadataReader
public interface MetadataReader { //配置类的资源对象 Resource getResource(); //类的元数据 ClassMetadata getClassMetadata(); //注解的元数据 AnnotationMetadata getAnnotationMetadata(); }
1
2
3
4
5
6
7
8
9
scanCandidateComponents 方法解析:
private Set<BeanDefinition> scanCandidateComponents(String basePackage) { LinkedHashSet candidates = new LinkedHashSet(); try { //组装扫描路径(组装完成后是这种格式:classpath*:cn/shiyujun/config/**/*.class) String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern; //根据路径获取资源对象 Resource[] resources = this.getResourcePatternResolver().getResources(packageSearchPath); boolean traceEnabled = this.logger.isTraceEnabled(); boolean debugEnabled = this.logger.isDebugEnabled(); Resource[] var7 = resources; int var8 = resources.length; for(int var9 = 0; var9 < var8; ++var9) { Resource resource = var7[var9]; if (traceEnabled) { this.logger.trace("Scanning " + resource); } if (resource.isReadable()) { try { //根据资源对象通过反射获取资源对象的MetadataReader,具体就不展开说了 MetadataReader metadataReader = this.getMetadataReaderFactory().getMetadataReader(resource); //查看配置类是否有@Conditional一系列的注解,然后是否满足注册Bean的条件 if (this.isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) { if (debugEnabled) { this.logger.debug("Identified candidate component class: " + resource); } candidates.add(sbd); } else if (debugEnabled) { this.logger.debug("Ignored because not a concrete top-level class: " + resource); } } else if (traceEnabled) { this.logger.trace("Ignored because not matching any filter: " + resource); } } catch (Throwable var13) { throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13); } } else if (traceEnabled) { this.logger.trace("Ignored because not readable: " + resource); } } return candidates; } catch (IOException var14) { throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54创建BeanDefinition
现在回到开始的
doScan
方法,直接进入registerBeanDefinition
到了一个比较重要的节点了,跟着上文的
registerBeanDefinition
方法走protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) { BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry); } public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { String beanName = definitionHolder.getBeanName(); // 注册bean,往下看 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); //如果存在别名则循环注册别名,逻辑跟上方差不多,就不展开了 String[] aliases = definitionHolder.getAliases(); if (aliases != null) { String[] var4 = aliases; int var5 = aliases.length; for(int var6 = 0; var6 < var5; ++var6) { String alias = var4[var6]; registry.registerAlias(beanName, alias); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23其实这个注册bean的方法是
DefaultListableBeanFactory
的方法,之前的文章已经解析过了,大体就是下面这么个流程@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(...); } } BeanDefinition oldBeanDefinition; // 所有的 Bean 注册后都会被放入到这个beanDefinitionMap 中,查看是否已存在这个bean oldBeanDefinition = this.beanDefinitionMap.get(beanName); // 处理重复名称的 Bean 定义的情况 if (oldBeanDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { // 如果不允许覆盖的话,抛异常 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // 用框架定义的 Bean 覆盖用户自定义的 Bean if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { // 用新的 Bean 覆盖旧的 Bean if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else { // log...用同等的 Bean 覆盖旧的 Bean if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } // 覆盖 this.beanDefinitionMap.put(beanName, beanDefinition); } else { // 判断是否已经有其他的 Bean 开始初始化了.注意,"注册Bean" 这个动作结束,Bean 依然还没有初始化 在 Spring 容器启动的最后,会 预初始化 所有的 singleton beans if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // 将 BeanDefinition 放到这个 map 中,这个 map 保存了所有的 BeanDefinition this.beanDefinitionMap.put(beanName, beanDefinition); // 这是个 ArrayList,所以会按照 bean 配置的顺序保存每一个注册的 Bean 的名字 this.beanDefinitionNames.add(beanName); // 这是个 LinkedHashSet,代表的是手动注册的 singleton bean, this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 1.2.1.3 、refresh()
首先整个方法进来以后跟使用XML的时候是一样的
# 与XML的不同点
obtainFreshBeanFactory()
方法 还记得在之前的文章中列出了好几万行代码来解析这个方法,但是回忆一个这个方法是干啥的来着,创建bean容器,但是呢,bean容器在scan方法里就已经创建好了,所以这里就没必要再进行额外的逻辑了,你看现在它的代码现在多简单protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; } protected final void refreshBeanFactory() throws IllegalStateException { if (!this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException( "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); } this.beanFactory.setSerializationId(getId()); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 2、基于注解的AOP源码解析
# 2.1、代码准备
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.11</version>
</dependency>
</dependencies>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public interface IOCService {
public String hollo();
}
public class IOCServiceImpl implements IOCService {
public String hollo() {
return "Hello,IOC";
}
}
//增加bean的配置类,以及启动AOP
@EnableAspectJAutoProxy
@Configuration
public class AnnotationConfig {
@Bean
public IOCService iocService(){
return new IOCServiceImpl();
}
}
//创建切点
@Aspect
@Component
public class AspectJTest {
@Pointcut("execution(public * cn.shiyujun.service.IOCService.hollo(..))")
public void testAOP(){}
@Before("testAOP()")
public void before(){
System.out.println("before testAOP...");
}
@After("testAOP()")
public void after(){
System.out.println("after testAOP...");
}
@Around("testAOP()")
public Object around(ProceedingJoinPoint p){
System.out.println("around before testAOP...");
Object o = null;
try {
o = p.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("around after testAOP...");
return o;
}
}
//启动Spring
public class AnnotationIOCDemo {
public static void main (String args[]){
ApplicationContext context = new AnnotationConfigApplicationContext("cn.shiyujun.config");
IOCService iocService=context.getBean(IOCService.class);
System.out.println(iocService.hollo());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 2.1.1、源码解析
# 2.1.1.1、@EnableAspectJAutoProxy注解
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({AspectJAutoProxyRegistrar.class}) public @interface EnableAspectJAutoProxy { //proxyTargetClass属性,默认false,尝试采用JDK动态代理织入增强(如果当前类没有实现接口则还是会使用CGLIB);如果设为true,则强制采用CGLIB动态代理织入增强 boolean proxyTargetClass() default false; //通过aop框架暴露该代理对象,aopContext能够访问。为了解决类内部方法之间调用时无法增强的问题 boolean exposeProxy() default false; }
1
2
3
4
5
6
7
8
9
10@Import注解:可以引入一个类,将这个类注入到Spring IOC容器中被当前Spring管理
看一下这个配置类的操作:
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { AspectJAutoProxyRegistrar() { } public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //注册一个AOP代理实现的Bean,往下看 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
registerAspectJAnnotationAutoProxyCreatorIfNecessary
方法的主要功能是注册或者升级AnnotationAwareAspectJAutoProxyCreator
类这个类在AOP中非常的重要,它的主要功能就是根据@Point注解定义的切点来自动代理与表达式匹配的类。 下面看一个这个实现的逻辑:
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null); } public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); } private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) { BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator"); //判断优先级,如果优先级较高则替换原先的bean if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } else { //注册AnnotationAwareAspectJAutoProxyCreator到容器中,此类负责基于注解的AOP动态代理实现 RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", -2147483648); beanDefinition.setRole(2); registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition); return beanDefinition; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 2.1.1.2 、AnnotationAwareAspectJAutoProxyCreator
先看一下类图
观察类图可知,AnnotationAwareAspectJAutoProxyCreator这个类间接实现了BeanPostProcessor接口。还记得我们之前在对SpringIOC的源码进行解析时提到过,Spring在实例化Bean的前后会分别调用方法
postProcessBeforeInstantiation
和postProcessAfterInstantiation
而AOP的整体逻辑就是通过这两个方法来实现的:
#
postProcessBeforeInstantiation
:首先看一下这个
postProcessBeforeInstantiation
方法,它是在bean实例化之前调用的,主要是针对切面类。这个方法不在AnnotationAwareAspectJAutoProxyCreator这个类中,而是在其父类AbstractAutoProxyCreator中:AbstractAutoProxyCreator#postProcessBeforeInstantiation
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { Object cacheKey = this.getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } //加载所有增强 if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } else { return null; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28上方代码中最重要的一个方法就是shouldSkip方法了,这个方法被AspectJAwareAdvisorAutoProxyCreator所重载:
protected boolean shouldSkip(Class<?> beanClass, String beanName) { //查找所有标识了@Aspect注解的类,这里是重点,接着往下看 List<Advisor> candidateAdvisors = this.findCandidateAdvisors(); Iterator var4 = candidateAdvisors.iterator(); Advisor advisor; do { if (!var4.hasNext()) { return super.shouldSkip(beanClass, beanName); } advisor = (Advisor)var4.next(); } while(!(advisor instanceof AspectJPointcutAdvisor) || !((AbstractAspectJAdvice)advisor.getAdvice()).getAspectName().equals(beanName)); return true; } protected List<Advisor> findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); return this.advisorRetrievalHelper.findAdvisorBeans(); } // AbstractAdvisorAutoProxyCreator#findCandidateAdvisors protected List<Advisor> findCandidateAdvisors() { List<Advisor> advisors = super.findCandidateAdvisors(); if (this.aspectJAdvisorsBuilder != null) { //buildAspectJAdvisors是重点 advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; } public List<Advisor> buildAspectJAdvisors() { //所有Aspect类的名称集合 List<String> aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized(this) { aspectNames = this.aspectBeanNames; //这个双重检查是不是在学习安全的单例模式的时候见过 if (aspectNames == null) { List<Advisor> advisors = new LinkedList(); List<String> aspectNames = new LinkedList(); //获取所有Bean名称 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false); String[] var18 = beanNames; int var19 = beanNames.length; for(int var7 = 0; var7 < var19; ++var7) { String beanName = var18[var7]; //判断是否符合条件,比如说有时会排除一些类,不让这些类注入进Spring if (this.isEligibleBean(beanName)) { Class<?> beanType = this.beanFactory.getType(beanName); //判断Bean的Class上是否标识@Aspect注解 if (beanType != null && this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //下一步说,重点的重点 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { //将解析的Bean名称及类上的增强缓存起来,每个Bean只解析一次 this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } } this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } else { List<Advisor> advisors = new LinkedList(); Iterator var3 = aspectNames.iterator(); while(var3.hasNext()) { String aspectName = (String)var3.next(); //从缓存中获取当前Bean的切面实例,如果不为空,则指明当前Bean的Class标识了@Aspect,且有切面方法 List<Advisor> cachedAdvisors = (List)this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109生成增强:
advisorFactory.getAdvisors方法会从@Aspect标识的类上获取@Before,@Pointcut等注解的信息及其标识的方法的信息,生成增强:
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //校验类的合法性相关 this.validate(aspectClass); MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new LinkedList(); //获取这个类所有的增强方法,下面讲解 Iterator var6 = this.getAdvisorMethods(aspectClass).iterator(); while(var6.hasNext()) { Method method = (Method)var6.next(); //生成增强实例 Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } Field[] var12 = aspectClass.getDeclaredFields(); int var13 = var12.length; for(int var14 = 0; var14 < var13; ++var14) { Field field = var12[var14]; Advisor advisor = this.getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; } //获取类的的方法 private List<Method> getAdvisorMethods(Class<?> aspectClass) { List<Method> methods = new LinkedList(); ReflectionUtils.doWithMethods(aspectClass, (method) -> { //在@Aspect标识的类内部排除@Pointcut标识之外的所有方法,得到的方法集合包括继承自父类的方法,包括继承自Object的方法 if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { methods.add(method); } }); //对得到的所有方法排序, //如果方法标识了切面注解,则按@Around, @Before, @After, @AfterReturning, @AfterThrowing的顺序排序 //如果没有标识这些注解,则按方法名称的字符串排序, //有注解的方法排在无注解的方法之前 //最后的排序应该是这样的Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class。。。 Collections.sort(methods, METHOD_COMPARATOR); return methods; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56调用生成增强实例的方法:getAdvisor()
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { //再次校验类的合法性 this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //切点表达式的包装类里面包含这些东西: //execution(public * cn.shiyujun.service.IOCService.hollo(..)) AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); //根据方法、切点、AOP实例工厂、类名、序号生成切面实例,详细代码往下看 return expressionPointcut == null ? null : new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); } private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { //查询方法上的切面注解,根据注解生成相应类型的AspectJAnnotation,在调用AspectJAnnotation的构造函数的同时 //根据注解value或pointcut属性得到切点表达式,有argNames则设置参数名称 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); //过滤那些不含@Before, @Around, @After, @AfterReturning, @AfterThrowing注解的方法 if (aspectJAnnotation == null) { return null; } else { //生成带表达式的切面切入点,设置其切入点表达式 AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]); ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); if (this.beanFactory != null) { ajexp.setBeanFactory(this.beanFactory); } return ajexp; } } //InstantiationModelAwarePointcutAdvisorImpl构造方法 public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { this.declaredPointcut = declaredPointcut; this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); this.methodName = aspectJAdviceMethod.getName(); this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); this.aspectJAdviceMethod = aspectJAdviceMethod; this.aspectJAdvisorFactory = aspectJAdvisorFactory; this.aspectInstanceFactory = aspectInstanceFactory; this.declarationOrder = declarationOrder; this.aspectName = aspectName; if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Pointcut preInstantiationPointcut = Pointcuts.union(aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { this.pointcut = this.declaredPointcut; this.lazy = false; //重点在这里 this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut); } } private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) { //再往下看 Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); return advice != null ? advice : EMPTY_ADVICE; } public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable { ... public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //又是一次校验 this.validate(candidateAspectClass); AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } else if (!this.isAspect(candidateAspectClass)) { throw new AopConfigException("Advice must be declared inside an aspect type: Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]"); } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Found AspectJ method: " + candidateAdviceMethod); } Object springAdvice; //根据注解类型生成不同的通知实例 switch(aspectJAnnotation.getAnnotationType()) { case AtBefore: springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfter: springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfterReturning: springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning()); } break; case AtAfterThrowing: springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing()); } break; case AtAround: springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtPointcut: if (this.logger.isDebugEnabled()) { this.logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } return null; default: throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod); } //设置通知方法所属的类 ((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName); //设置通知的序号,同一个类中有多个切面注解标识的方法时,按上方说的排序规则来排序, //其序号就是此方法在列表中的序号,第一个就是0 ((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrder); //获取通知方法的所有参数 String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); //将通知方法上的参数设置到通知中 if (argNames != null) { ((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames); } //计算参数绑定工作,此方法详解请接着往下看 ((AbstractAspectJAdvice)springAdvice).calculateArgumentBindings(); return (Advice)springAdvice; } } ... } //校验方法参数并绑定 public final synchronized void calculateArgumentBindings() { if (!this.argumentsIntrospected && this.parameterTypes.length != 0) { int numUnboundArgs = this.parameterTypes.length; Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes(); //切面注解标识的方法第一个参数要求是JoinPoint,或StaticPart,若是@Around注解则也可以是ProceedingJoinPoint if (!this.maybeBindJoinPoint(parameterTypes[0]) && !this.maybeBindProceedingJoinPoint(parameterTypes[0])) { if (this.maybeBindJoinPointStaticPart(parameterTypes[0])) { --numUnboundArgs; } } else { --numUnboundArgs; } if (numUnboundArgs > 0) { //绑定属性 this.bindArgumentsByName(numUnboundArgs); } this.argumentsIntrospected = true; } } private void bindArgumentsByName(int numArgumentsExpectingToBind) { if (this.argumentNames == null) { //获取方法参数的名称 this.argumentNames = this.createParameterNameDiscoverer().getParameterNames(this.aspectJAdviceMethod); } if (this.argumentNames != null) { // 往下看 this.bindExplicitArguments(numArgumentsExpectingToBind); } else { throw new IllegalStateException("Advice method [" + this.aspectJAdviceMethod.getName() + "] requires " + numArgumentsExpectingToBind + " arguments to be bound by name, but the argument names were not specified and could not be discovered."); } } private void bindExplicitArguments(int numArgumentsLeftToBind) { Assert.state(this.argumentNames != null, "No argument names available"); //此属性用来存储方法未绑定的参数名称,及参数的序号 this.argumentBindings = new HashMap(); int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterCount(); if (this.argumentNames.length != numExpectedArgumentNames) { throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames + " arguments to bind by name in advice, but actually found " + this.argumentNames.length + " arguments."); } else { // So we match in number...,argumentIndexOffset代表第一个未绑定参数的顺序 int argumentIndexOffset = this.parameterTypes.length - numArgumentsLeftToBind; for(int i = argumentIndexOffset; i < this.argumentNames.length; ++i) { //存储未绑定的参数名称及其顺序的映射关系 this.argumentBindings.put(this.argumentNames[i], i); } Integer index; //如果是@AfterReturning注解的returningName 有值,验证,解析,同时得到定义返回值的类型 if (this.returningName != null) { if (!this.argumentBindings.containsKey(this.returningName)) { throw new IllegalStateException("Returning argument name '" + this.returningName + "' was not bound in advice arguments"); } index = (Integer)this.argumentBindings.get(this.returningName); this.discoveredReturningType = this.aspectJAdviceMethod.getParameterTypes()[index]; this.discoveredReturningGenericType = this.aspectJAdviceMethod.getGenericParameterTypes()[index]; } if (this.throwingName != null) { if (!this.argumentBindings.containsKey(this.throwingName)) { throw new IllegalStateException("Throwing argument name '" + this.throwingName + "' was not bound in advice arguments"); } index = (Integer)this.argumentBindings.get(this.throwingName); this.discoveredThrowingType = this.aspectJAdviceMethod.getParameterTypes()[index]; } this.configurePointcutParameters(this.argumentNames, argumentIndexOffset); } } private void configurePointcutParameters(String[] argumentNames, int argumentIndexOffset) { int numParametersToRemove = argumentIndexOffset; if (this.returningName != null) { numParametersToRemove = argumentIndexOffset + 1; } if (this.throwingName != null) { ++numParametersToRemove; } String[] pointcutParameterNames = new String[argumentNames.length - numParametersToRemove]; Class<?>[] pointcutParameterTypes = new Class[pointcutParameterNames.length]; Class<?>[] methodParameterTypes = this.aspectJAdviceMethod.getParameterTypes(); int index = 0; for(int i = 0; i < argumentNames.length; ++i) { if (i >= argumentIndexOffset && !argumentNames[i].equals(this.returningName) && !argumentNames[i].equals(this.throwingName)) { pointcutParameterNames[index] = argumentNames[i]; pointcutParameterTypes[index] = methodParameterTypes[i]; ++index; } } //剩余的未绑定的参数会赋值给AspectJExpressionPointcut(表达式形式的切入点)的属性,以备后续使用 this.pointcut.setParameterNames(pointcutParameterNames); this.pointcut.setParameterTypes(pointcutParameterTypes); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# 2.1.1.3、postProcessAfterInitialization
这个方法是在bean实例化之后调用的,它是适用于所有需要被代理的类的
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = this.getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return this.wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //如果已经处理过 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; //如果当前类是增强类 } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; //查看类是否是基础设施类,或者是否被排除 } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) { //校验此类是否应该被代理,获取这个类的增强 Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null); //如果获取到了增强则需要针对增强创建代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //创建代理 Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } else { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } } else { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40上方这段代理一共有两个重点,
getAdvicesAndAdvisorsForBean
和createProxy
这两个方法protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName); return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray(); } protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //获取容器中的所有增强 List<Advisor> candidateAdvisors = this.findCandidateAdvisors(); //验证beanClass是否该被代理,如果被代理,则返回适用于这个bean的增强 List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); this.extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = this.sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16上方这个获取增强又分成了2部分,获取全部和根据全部处理bean相关的
protected List<Advisor> findCandidateAdvisors() { // 调用父类的方法加载配置文件中的AOP声明(注解与XML都存在的时候) List<Advisor> advisors = super.findCandidateAdvisors(); //往下看 if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
1
2
3
4
5
6
7
8
9
10下面的方法就是获取所有的增强的代码实现了,方法比较长,不过主要逻辑很少。
1.获取所有beanName
2.找出所有标记Aspect注解的类
3.对标记Aspect的类提取增强器
public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized(this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new LinkedList(); List<String> aspectNames = new LinkedList(); //获取所有的bean String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false); String[] var18 = beanNames; int var19 = beanNames.length; for(int var7 = 0; var7 < var19; ++var7) { String beanName = var18[var7]; //校验不合法的类,Spring的一个扩展点,可以从子类中做排除切面的操作 if (this.isEligibleBean(beanName)) { //获取bean的类型 Class<?> beanType = this.beanFactory.getType(beanName); //是否带有Aspect注解 if (beanType != null && this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //解析所有的增强方法,下面说 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } } this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } else { List<Advisor> advisors = new LinkedList(); Iterator var3 = aspectNames.iterator(); while(var3.hasNext()) { String aspectName = (String)var3.next(); List<Advisor> cachedAdvisors = (List)this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76接下来就是各个增强器的获取方法的实现:
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //获取所有Aspect类、类名称、并校验 Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); this.validate(aspectClass); MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new LinkedList(); //取出类的所有方法 Iterator var6 = this.getAdvisorMethods(aspectClass).iterator(); while(var6.hasNext()) { Method method = (Method)var6.next(); //获取增强方法,往下看 Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } // 如果需要增强且配置了延迟增强则在第一个位置添加同步实例化增强方法 if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } // 获取属性中配置DeclareParents注解的增强 Field[] var12 = aspectClass.getDeclaredFields(); int var13 = var12.length; for(int var14 = 0; var14 < var13; ++var14) { Field field = var12[var14]; Advisor advisor = this.getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; } //普通增强的获取 public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //获取切点 AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); //根据切点生成增强 return expressionPointcut == null ? null : new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); } //上方代码又分为了两部分,先看一下切点信息的获取 public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { this.declaredPointcut = declaredPointcut; this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); this.methodName = aspectJAdviceMethod.getName(); this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); this.aspectJAdviceMethod = aspectJAdviceMethod; this.aspectJAdvisorFactory = aspectJAdvisorFactory; this.aspectInstanceFactory = aspectInstanceFactory; this.declarationOrder = declarationOrder; this.aspectName = aspectName; if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Pointcut preInstantiationPointcut = Pointcuts.union(aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { this.pointcut = this.declaredPointcut; this.lazy = false; //初始化对应的增强器,重点 this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut); } } //到这里之后获取所有的增强这个流程就快要完毕了 private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) { //往下看 Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); return advice != null ? advice : EMPTY_ADVICE; } public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); this.validate(candidateAspectClass); AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } else if (!this.isAspect(candidateAspectClass)) { throw new AopConfigException("Advice must be declared inside an aspect type: Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]"); } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Found AspectJ method: " + candidateAdviceMethod); } Object springAdvice; //根据不同的注解类型封装不同的增强器 switch(aspectJAnnotation.getAnnotationType()) { case AtBefore: springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfter: springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfterReturning: springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning()); } break; case AtAfterThrowing: springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing()); } break; case AtAround: springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtPointcut: if (this.logger.isDebugEnabled()) { this.logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } return null; default: throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod); } ((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName); ((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrder); String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); if (argNames != null) { ((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames); } ((AbstractAspectJAdvice)springAdvice).calculateArgumentBindings(); return (Advice)springAdvice; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145经过上方的长篇大论,我们终于完成了所有的增强器的解析
接着最上方的方法继续分析:
findAdvisorsThatCanApply
protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { //往下看 return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } } public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new LinkedList<Advisor>(); for (Advisor candidate : candidateAdvisors) { //处理引介增强,重点,再往下看 if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { continue; } //对普通bean的处理 if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36引介增强与普通bean的处理最后都是进的同一个方法,只不过是引介增强的第三个参数默认使用的false
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { //如果存在排除的配置 if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; //往下看 return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { return true; } } public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); //切点上是否存在排除类的配置 if (!pc.getClassFilter().matches(targetClass)) { return false; } //验证注解的作用域是否可以作用于方法上 MethodMatcher methodMatcher = pc.getMethodMatcher(); if (methodMatcher == MethodMatcher.TRUE) { return true; } IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); for (Class<?> clazz : classes) { Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { //获取类所实现的所有接口和所有类层级的方法,循环验证 if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || methodMatcher.matches(method, targetClass)) { return true; } } } return false; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48现在所有的bean对应的增强都已经获取到了,那么就可以根据类的所有增强数组创建代理
# 2.1.1.4、createProxy
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); // 使用proxyFactory对象copy当前类中的相关属性 proxyFactory.copyFrom(this); //判断是否使用Cglib动态代理 if (!proxyFactory.isProxyTargetClass()) { //如果配置开启使用则直接设置开启 if (this.shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { //如果没有配置开启则判断bean是否有合适的接口使用JDK的动态代理(JDK动态代理必须是带有接口的类,如果类没有实现任何接口则只能使用Cglib动态代理) this.evaluateProxyInterfaces(beanClass, proxyFactory); } } //添加所有增强 Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); //设置要代理的类 proxyFactory.setTargetSource(targetSource); //Spring的一个扩展点,默认实现为空。留给我们在需要对代理进行特殊操作的时候实现 this.customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (this.advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } //使用代理工厂获取代理对象 下面分析 return proxyFactory.getProxy(this.getProxyClassLoader()); } public Object getProxy(@Nullable ClassLoader classLoader) { return this.createAopProxy().getProxy(classLoader); } protected final synchronized AopProxy createAopProxy() { if (!this.active) { this.activate(); } return this.getAopProxyFactory().createAopProxy(this); } public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) { return new JdkDynamicAopProxy(config); } else { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation."); } else { return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config)); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
代理创建出来了,那么我们的前置增强、后置增强、环绕增强等是如何在代理中体现的呢:
简单看一下JDK动态代理的实现:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
//equals方法处理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
//hash代码处理
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//如果配置内部方法调用的增强
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取当前方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
//如果没有拦截器直接调用切点方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//执行拦截器链,重点,往下看
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
//返回结果
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
看完上方的代码,可以猜到,所有的增强都在这个拦截器里面了,那么这个拦截器又是如何实现的呢
public Object proceed() throws Throwable {
// 执行完所有的增强后执行切点方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//获取下一个要执行的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
至此SpringAOP的源码解析已经完成!
# 3、Spring JDBC源码解析
# 3.1、传统JDBC
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2. 获得数据库连接
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//3.操作数据库
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT name, age from user");
//4.处理返回值
while(rs.next()){
System.out.println("名字:"+rs.getString("name")+" 年龄:"+rs.getInt("age"));
}
2
3
4
5
6
7
8
9
10
11
# 3.2、Spring JDBC
1、引入Maven
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.18</version>
</dependency>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2、实体类
public class User {
private int id;
private String name;
private int age;
//getter、setter省略
}
2
3
4
5
6
3、返回值处理类
public class UserRowMapper implements RowMapper {
@Nullable
public Object mapRow(ResultSet resultSet, int i) throws SQLException {
User user=new User();
user.setId(resultSet.getInt("id"));
user.setName(resultSet.getString("name"));
user.setAge(resultSet.getInt("age"));
return user;
}
}
2
3
4
5
6
7
8
9
10
4、业务处理类
public interface JDBCService {
public void queryById(int id);
public void updateNameById(int id,String name);
}
public class JDBCServiceImpl implements JDBCService {
private JdbcTemplate jdbcTemplate;
public JDBCServiceImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void queryById(int id) {
List<User> list = jdbcTemplate.query("select id,name,age from user where id=?", new Object[]{id}, new UserRowMapper());
if (list.size() > 0) {
System.out.println("id 为" + id + "的用户名为:" + list.get(0).getName());
}
}
public void updateNameById(int id, String name) {
jdbcTemplate.update("update user set name=? where id=?", new Object[]{name, id}, new UserRowMapper());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
5、配置类
@Configuration
public class JDBCConfig {
@Bean
public DruidDataSource druidDataSource(){
DruidDataSource druidDataSource=new DruidDataSource();
druidDataSource.setUsername("root");
druidDataSource.setPassword("123456");
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://172.16.40.159:3306/cfkk?characterEncoding=utf-8&useSSL=false");
return druidDataSource;
}
@Bean
public JDBCService jdbcService(DruidDataSource druidDataSource){
JdbcTemplate jdbcTemplate=new JdbcTemplate(druidDataSource);
JDBCService jdbcService=new JDBCServiceImpl(jdbcTemplate);
return jdbcService;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
6、启动类
public class JDBCDemo {
public static void main (String args[]){
ApplicationContext context = new AnnotationConfigApplicationContext("cn.shiyujun.config");
JDBCService jdbcService= context.getBean(JDBCService.class);
jdbcService.updateNameById(1,"李四");
jdbcService.queryById(1);
}
}
2
3
4
5
6
7
8
# 3.3 、update
public int update(String sql, @Nullable Object... args) throws DataAccessException { return this.update(sql, this.newArgPreparedStatementSetter(args)); } public int update(String sql, @Nullable PreparedStatementSetter pss) throws DataAccessException { return this.update((PreparedStatementCreator)(new JdbcTemplate.SimplePreparedStatementCreator(sql)), (PreparedStatementSetter)pss); } protected int update(PreparedStatementCreator psc, @Nullable PreparedStatementSetter pss) throws DataAccessException { this.logger.debug("Executing prepared SQL update"); return updateCount((Integer)this.execute(psc, (ps) -> { Integer var4; try { if (pss != null) { //设置所需的全部参数 pss.setValues(ps); } //调用jdbc的更新方法 int rows = ps.executeUpdate(); if (this.logger.isDebugEnabled()) { this.logger.debug("SQL update affected " + rows + " rows"); } var4 = rows; } finally { if (pss instanceof ParameterDisposer) { ((ParameterDisposer)pss).cleanupParameters(); } } return var4; })); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35先使用ArgPreparedStatementSetter对参数进行了一层封装,然后使用SimplePreparedStatementCreator对Sql进行了一层封装,最后执行核心逻辑。总共涉及到四个方法updateCount()、execute()、setValues()、executeUpdate()
1、updateCount()
private static int updateCount(@Nullable Integer result) { Assert.state(result != null, "No update count"); return result; }
1
2
3
42、execute() : 这里完成了传统JDBC的前两步
加载驱动和获取连接
public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException { Assert.notNull(psc, "PreparedStatementCreator must not be null"); Assert.notNull(action, "Callback object must not be null"); if (this.logger.isDebugEnabled()) { String sql = getSql(psc); this.logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : "")); } //根据具体的连接池组件获取数据库连接,这里就不深入研究了,放到以后的连接池源码解析里 Connection con = DataSourceUtils.getConnection(this.obtainDataSource()); PreparedStatement ps = null; Object var13; try { //应该对这个PreparedStatement印象很深刻了 ps = psc.createPreparedStatement(con); this.applyStatementSettings(ps); //调用回调函数也就是update方法中execute的lambda表达式里的逻辑 T result = action.doInPreparedStatement(ps); //警告处理 this.handleWarnings((Statement)ps); var13 = result; } catch (SQLException var10) { if (psc instanceof ParameterDisposer) { ((ParameterDisposer)psc).cleanupParameters(); } String sql = getSql(psc); // 释放资源 JdbcUtils.closeStatement(ps); ps = null; DataSourceUtils.releaseConnection(con, this.getDataSource()); con = null; throw this.translateException("PreparedStatementCallback", sql, var10); } finally { if (psc instanceof ParameterDisposer) { ((ParameterDisposer)psc).cleanupParameters(); } JdbcUtils.closeStatement(ps); DataSourceUtils.releaseConnection(con, this.getDataSource()); } return var13; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
453、setValues():
public void setValues(PreparedStatement ps) throws SQLException { if (this.args != null) { for(int i = 0; i < this.args.length; ++i) { Object arg = this.args[i]; this.doSetValue(ps, i + 1, arg); } } } protected void doSetValue(PreparedStatement ps, int parameterPosition, Object argValue) throws SQLException { if (argValue instanceof SqlParameterValue) { SqlParameterValue paramValue = (SqlParameterValue)argValue; StatementCreatorUtils.setParameterValue(ps, parameterPosition, paramValue, paramValue.getValue()); } else { StatementCreatorUtils.setParameterValue(ps, parameterPosition, -2147483648, argValue); } } private static void setParameterValueInternal(PreparedStatement ps, int paramIndex, int sqlType, @Nullable String typeName, @Nullable Integer scale, @Nullable Object inValue) throws SQLException { String typeNameToUse = typeName; int sqlTypeToUse = sqlType; Object inValueToUse = inValue; if (inValue instanceof SqlParameterValue) { SqlParameterValue parameterValue = (SqlParameterValue)inValue; if (logger.isDebugEnabled()) { logger.debug("Overriding type info with runtime info from SqlParameterValue: column index " + paramIndex + ", SQL type " + parameterValue.getSqlType() + ", type name " + parameterValue.getTypeName()); } if (parameterValue.getSqlType() != -2147483648) { sqlTypeToUse = parameterValue.getSqlType(); } if (parameterValue.getTypeName() != null) { typeNameToUse = parameterValue.getTypeName(); } inValueToUse = parameterValue.getValue(); } if (logger.isTraceEnabled()) { logger.trace("Setting SQL statement parameter value: column index " + paramIndex + ", parameter value [" + inValueToUse + "], value class [" + (inValueToUse != null ? inValueToUse.getClass().getName() : "null") + "], SQL type " + (sqlTypeToUse == -2147483648 ? "unknown" : Integer.toString(sqlTypeToUse))); } if (inValueToUse == null) { setNull(ps, paramIndex, sqlTypeToUse, typeNameToUse); } else { setValue(ps, paramIndex, sqlTypeToUse, typeNameToUse, scale, inValueToUse); } } private static void setValue(PreparedStatement ps, int paramIndex, int sqlType, @Nullable String typeName, @Nullable Integer scale, Object inValue) throws SQLException { if (inValue instanceof SqlTypeValue) { ((SqlTypeValue)inValue).setTypeValue(ps, paramIndex, sqlType, typeName); } else if (inValue instanceof SqlValue) { ((SqlValue)inValue).setValue(ps, paramIndex); } else if (sqlType != 12 && sqlType != -9 && sqlType != -1 && sqlType != -16) { if ((sqlType == 2005 || sqlType == 2011) && isStringValue(inValue.getClass())) { String strVal = inValue.toString(); if (strVal.length() > 4000) { if (sqlType == 2011) { ps.setNClob(paramIndex, new StringReader(strVal), (long)strVal.length()); } else { ps.setClob(paramIndex, new StringReader(strVal), (long)strVal.length()); } return; } ps.setString(paramIndex, strVal); } else if (sqlType != 3 && sqlType != 2) { if (sqlType == 16) { if (inValue instanceof Boolean) { ps.setBoolean(paramIndex, (Boolean)inValue); } else { ps.setObject(paramIndex, inValue, 16); } } else { Calendar cal; if (sqlType == 91) { if (inValue instanceof Date) { if (inValue instanceof java.sql.Date) { ps.setDate(paramIndex, (java.sql.Date)inValue); } else { ps.setDate(paramIndex, new java.sql.Date(((Date)inValue).getTime())); } } else if (inValue instanceof Calendar) { cal = (Calendar)inValue; ps.setDate(paramIndex, new java.sql.Date(cal.getTime().getTime()), cal); } else { ps.setObject(paramIndex, inValue, 91); } } else if (sqlType == 92) { if (inValue instanceof Date) { if (inValue instanceof Time) { ps.setTime(paramIndex, (Time)inValue); } else { ps.setTime(paramIndex, new Time(((Date)inValue).getTime())); } } else if (inValue instanceof Calendar) { cal = (Calendar)inValue; ps.setTime(paramIndex, new Time(cal.getTime().getTime()), cal); } else { ps.setObject(paramIndex, inValue, 92); } } else if (sqlType == 93) { if (inValue instanceof Date) { if (inValue instanceof Timestamp) { ps.setTimestamp(paramIndex, (Timestamp)inValue); } else { ps.setTimestamp(paramIndex, new Timestamp(((Date)inValue).getTime())); } } else if (inValue instanceof Calendar) { cal = (Calendar)inValue; ps.setTimestamp(paramIndex, new Timestamp(cal.getTime().getTime()), cal); } else { ps.setObject(paramIndex, inValue, 93); } //默认都是进入这个判断-2147483648 } else if (sqlType == -2147483648 || sqlType == 1111 && "Oracle".equals(ps.getConnection().getMetaData().getDatabaseProductName())) { //除了String\date\Calendar之外,别的全部都是setObject if (isStringValue(inValue.getClass())) { ps.setString(paramIndex, inValue.toString()); } else if (isDateValue(inValue.getClass())) { ps.setTimestamp(paramIndex, new Timestamp(((Date)inValue).getTime())); } else if (inValue instanceof Calendar) { cal = (Calendar)inValue; ps.setTimestamp(paramIndex, new Timestamp(cal.getTime().getTime()), cal); } else { ps.setObject(paramIndex, inValue); } } else { ps.setObject(paramIndex, inValue, sqlType); } } } else if (inValue instanceof BigDecimal) { ps.setBigDecimal(paramIndex, (BigDecimal)inValue); } else if (scale != null) { ps.setObject(paramIndex, inValue, sqlType, scale); } else { ps.setObject(paramIndex, inValue, sqlType); } } else { ps.setString(paramIndex, inValue.toString()); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# 3.4、query
public <T> List<T> query(String sql, @Nullable Object[] args, RowMapper<T> rowMapper) throws DataAccessException { return (List)result(this.query((String)sql, (Object[])args, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper)))); } public <T> T query(String sql, @Nullable Object[] args, ResultSetExtractor<T> rse) throws DataAccessException { return this.query(sql, this.newArgPreparedStatementSetter(args), rse); } public <T> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse) throws DataAccessException { return this.query((PreparedStatementCreator)(new JdbcTemplate.SimplePreparedStatementCreator(sql)), (PreparedStatementSetter)pss, (ResultSetExtractor)rse); } public <T> T query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse) throws DataAccessException { Assert.notNull(rse, "ResultSetExtractor must not be null"); this.logger.debug("Executing prepared SQL query"); //这里的execute的逻辑与update是一样的 return this.execute(psc, new PreparedStatementCallback<T>() { @Nullable public T doInPreparedStatement(PreparedStatement ps) throws SQLException { ResultSet rs = null; Object var3; try { if (pss != null) { pss.setValues(ps); } rs = ps.executeQuery(); //这里是重点 var3 = rse.extractData(rs); } finally { JdbcUtils.closeResultSet(rs); if (pss instanceof ParameterDisposer) { ((ParameterDisposer)pss).cleanupParameters(); } } return var3; } }); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
431、**处理返回值 **rse.extractData(rs)
RowMapperResultSetExtractor#extractData public List<T> extractData(ResultSet rs) throws SQLException { List<T> results = this.rowsExpected > 0 ? new ArrayList(this.rowsExpected) : new ArrayList(); int var3 = 0; while(rs.next()) { //在这里就是调用的我们一开始定义的UserRowMapper的mapRow方法 results.add(this.rowMapper.mapRow(rs, var3++)); } return results; }
1
2
3
4
5
6
7
8
9
10
11
12
13
# 4、@Import注解源码解析
Spring 3.0之前,创建Bean可以通过xml配置文件与扫描特定包下面的类来将类注入到Spring IOC容器内。
而在Spring 3.0之后提供了JavaConfig的方式,也就是将IOC容器里Bean的元信息以java代码的方式进行描述。我们可以通过@Configuration与@Bean这两个注解配合使用来将原来配置在xml文件里的bean通过java代码的方式进行描述
@Import注解提供了@Bean注解的功能,同时还有xml配置文件里标签组织多个分散的xml文件的功能,当然在这里是组织多个分散的@Configuration
先看一下@Import注解的源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
Class<?>[] value();
}
2
3
4
5
6
7
8
9
10
11
1、@Import可以配合
Configuration
,ImportSelector
,ImportBeanDefinitionRegistrar
来使用,下面的or表示也可以把Import当成普通的Bean使用2、@Import只允许放到类上面,不能放到方法上。
下面我们来看具体的使用方式:
# 4.1、普通使用方法:
这种方法可以把类直接加载到SpringIOC容器中
@Configuration @Import(value={UserServiceImpl.class}) public class Config { }
1
2
3
4
5但是这种方式有一些问题,那就是只能使用类的无参构造方法来创建bean,对于有参数的构造方法就无能为力了
# 4.2、结合ImportBeanDefinitionRegistrar
接口使用
先看一下ImportBeanDefinitionRegistrar接口的源码
public interface ImportBeanDefinitionRegistrar { void registerBeanDefinitions(AnnotationMetadata var1, BeanDefinitionRegistry var2); } 接口有两个参数 AnnotationMetadata:通过这个参数可以拿到类的元数据信息 BeanDefinitionRegistry:通过这个参数可以操作IOC容器
1
2
3
4
5
6自己写一个类实现这个接口
public class UserServiceBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) { BeanDefinitionBuilder JDBCServiceImpl = BeanDefinitionBuilder.rootBeanDefinition(JDBCServiceImpl.class); registry.registerBeanDefinition("JDBCServiceImpl", JDBCServiceImpl.getBeanDefinition()); } } 可以看到我们在这个方法里面做一些特殊操作什么的都是可以的,相比较于普通的方式可是灵活了很多
1
2
3
4
5
6
7
8接着我们在@Import注解引入的地方只需要修改为引入UserServiceBeanDefinitionRegistrar就可以了
@Configuration @Import(value={UserServiceBeanDefinitionRegistrar.class}) public class Config { }
1
2
3
4
5
# 4.3、结合ImportSelector接口
相比较与实现
ImportBeanDefinitionRegistrar
接口之后直接操作Bean容器来说,使用ImportSelector
会更加优雅一些,只需要返回需要注入类的全限定名就可以了ImportSelector接口的源码如下:
public interface ImportSelector { String[] selectImports(AnnotationMetadata importingClassMetadata); } public class UserServiceImportSelect implements ImportSelector{ public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{UserServiceImpl.class.getName()}; } } @Configuration() @Import(value={UserServiceImportSelect.class}) public class Config { }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 4.4 、源码解析
看过之前Spring源码解析文章的同学都知道,
refresh
方法是用来初始化容器上下文的。跟着这个调用链走下来到中间有一个类是ConfigurationClassPostProcessor
,根据类名我们就可以猜到这个类应该是处理配置类(也就是标注@Configuration
)的。那么从这开始看吧
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//查看是否是配置类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
//如果没有配置类就直接返回
if (configCandidates.isEmpty()) {
return;
}
//对这些配置类根据Order排序
Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
@Override
public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}
});
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
//创建配置类的解析类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
do {
//ConfigurationClassParser的parse方法进行解析,重点哈
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<String>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
if (sbr != null) {
if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
// ConfigurationClassParser#parse
public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
processDeferredImportSelectors();
}
//下面三种方法用于处理不同的BeanDefinition 类型,但最终都是使用的processConfigurationClass方法
protected final void parse(String className, String beanName) throws IOException {
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
processConfigurationClass(new ConfigurationClass(reader, beanName));
}
protected final void parse(Class<?> clazz, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(clazz, beanName));
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
//可以看到配置类可能会是三种形式的存在,这三种形式的Bean在操作上有着部分不一样,但是大部分又是一样,所以Spring用这种模式来处理。
//接着往下看:
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
//在这里处理Configuration重复import
//如果同一个配置类被处理两次,两次都属于被import的则合并导入类,返回。如果配置类不是被导入的,则移除旧使用新的配置类
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
return;
}
else {
this.configurationClasses.remove(configClass);
for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext();) {
if (configClass.equals(it.next())) {
it.remove();
}
}
}
}
SourceClass sourceClass = asSourceClass(configClass);
do {
//接着往下看吧
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
//我们经常见的`@Bean`、`@ImportResource` 、`@Import`、`@ComponentScan`、`@PropertySource`都是在这里处理的
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// 处理递归类
processMemberClasses(configClass, sourceClass);
// 处理@PropertySource注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 处理 @ComponentScan 注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
//处理Import注解
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 处理@ImportResource 注解
if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
//处理包含@Bean注解的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 处理普通方法
processInterfaces(configClass, sourceClass);
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
return null;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
处理Import注解
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
//如果实现了ImportSelector接口
if (candidate.isAssignable(ImportSelector.class)) {
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
//如果实现了ImportBeanDefinitionRegistrar接口
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
//将import当成Configuration来使用就是我们的第一种应用的方式
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 5、Spring事务源码解析
事务是通过
EnableTransactionManagement
注解启用的,所以此次源码解析也从此注解开始
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default 2147483647;
}
2
3
4
5
6
7
8
9
10
11
直接看@Import导入的类:
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
public TransactionManagementConfigurationSelector() {
}
protected String[] selectImports(AdviceMode adviceMode) {
switch(adviceMode) {
case PROXY:
return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
default:
return null;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
可以看到这里是根据
@EnableTransactionManagement
注解的mode
属性来确认注入哪一个配置类。这里由于我们没有指定属性,所以使用的默认的PROXY代理,走的是第一个case所以在这里往Spring容器中注入了两个bean
AutoProxyRegistrar
、ProxyTransactionManagementConfiguration
# 5.1、创建自动代理的构建器AutoProxyRegistrar
AutoProxyRegistrar类里面核心方法只有一个registerBeanDefinitions
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
//获取注解元信息
Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
Iterator var5 = annoTypes.iterator();
while(var5.hasNext()) {
String annoType = (String)var5.next();
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
if (candidate != null) {
Object mode = candidate.get("mode");
Object proxyTargetClass = candidate.get("proxyTargetClass");
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) {
//由于咱们使用的默认PROXY所以走这个分支 往下看-1
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
//强制使用Cglib动态代理
if ((Boolean)proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
}
if (!candidateFound) {
String name = this.getClass().getSimpleName();
this.logger.warn(String.format("%s was imported but no annotations were found having both 'mode' and 'proxyTargetClass' attributes of type AdviceMode and boolean respectively. This means that auto proxy creator registration and configuration may not have occurred as intended, and components may not be proxied as expected. Check to ensure that %s has been @Import'ed on the same class where these annotations are declared; otherwise remove the import of %s altogether.", name, name, name));
}
}
//往下看-1:
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, (Object)null);
}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 定义有AUTO_PROXY_CREATOR_BEAN_NAME="org.springframework.aop.config.internalAutoProxyCreator"
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
// 如果容器中已经存在自动代理构建器,则比较两个构建器的优先级
if (currentPriority < requiredPriority) {
// 保存优先级高的构建器
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
} else {
// 如果容器中还没有自动代理构建器
// 则创建构建器相应的BeanDefinition对象
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
// 向容器中注册代理构建器的BeanDefinition对象
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
上述的主要流程就是为了org.springframework.aop.config.internalAutoProxyCreator这个bean的注册
# 5.2、ProxyTransactionManagementConfiguration
# 事务核心bean:完成了整个Spring的事务功能,先看源码
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
public ProxyTransactionManagementConfiguration() {
}
@Bean(
name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
)
@Role(2)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(this.transactionAttributeSource());
advisor.setAdvice(this.transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder((Integer)this.enableTx.getNumber("order"));
}
return advisor;
}
@Bean
@Role(2)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(2)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 5.2.1、获取增强:
在阅读完AOP的原理之后,我们知道,当一个bean实例化之后会尝试获取所有适用于此Bean的增强。而在上篇文章中,我们已经发现了,
@EnableTransactionManagement
注解会往Spring中注入一个增强BeanFactoryTransactionAttributeSourceAdvisor
。经过一番代码调用以后,会进入这么一个方法,这里的第一个入参就是BeanFactoryTransactionAttributeSourceAdvisor
增强
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
//获取当前类的所有方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
到这里的时候就进入事务相关的类TransactionAttributeSourcePointcut
,看名字就能知道,这是个切点类.那么接下来的逻辑应该可以想象到,无非就是判断是否是个事务方法
public boolean matches(Method method, @Nullable Class<?> targetClass) {
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
2
3
4
5
6
7
如果是事务方法则继续往下走:
public TransactionAttribute getTransactionAttribute(Method method,
@Nullable Class<?> targetClass) {
// 如果当前方法是Object类中的方法,则直接返回
if (method.getDeclaringClass() == Object.class) {
return null;
}
// 获取当前方法缓存使用的key
Object cacheKey = getCacheKey(method, targetClass);
Object cached = this.attributeCache.get(cacheKey);
// 从缓存中获取当前方法解析的事务属性,如果解析过,则将解析结果返回
if (cached != null) {
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
} else {
return (TransactionAttribute) cached;
}
} else {
// 解析当前方法的事务属性,这里很重要,下面说
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
if (txAttr == null) {
// 如果当前方法上没有事务属性,则缓存一个表示空事务属性的对象
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
} else {
// 获取方法的签名
String methodIdentification =
ClassUtils.getQualifiedMethodName(method, targetClass);
// 如果生成的事务属性是DefaultTransactionAttribute类型的,则将方法签名设置到其descriptor属性中
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr)
.setDescriptor(methodIdentification);
}
if (logger.isDebugEnabled()) {
logger.debug("Adding transactional method '" + methodIdentification
+ "' with attribute: " + txAttr);
}
// 缓存当前方法的解析结果
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
接着看一下方法的事务属性是如何解析的:
protected TransactionAttribute computeTransactionAttribute(Method method,
@Nullable Class<?> targetClass) {
// 如果设置了只对public方法进行事务代理,并且当前方法不是public的,则返回null
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
Class<?> userClass = (targetClass != null ?
ClassUtils.getUserClass(targetClass) : null);
// 获取最为准确的方法,即如果传入的method只是一个接口方法,则会去找其实现类的同一方法进行解析
Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
// 如果当前方法是一个泛型方法,则会找Class文件中实际实现的方法
specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
// 解析目标方法,获取其是否存在事务属性,如果存在则直接返回
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// 解析目标方法所在的类,判断其是否标注有事务属性,如果存在,并且目标方法是用户实现的方法,则直接返回
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
// 如果通过解析到的方法无法找到事务属性,则判断解析得到的方法与传入的目标方法是否为同一个方法,
// 如果不是同一个方法,则尝试对传入的方法及其所在的类进行事务属性解析
if (specificMethod != method) {
// 对传入方法解析事务属性,如果存在,则直接返回
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// 对传入方法所在类进行事务属性解析,如果存在,则直接返回
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
这里对事务属性的解析主要分为对目标方法进行解析和对传入方法进行解析,接着看findTransactionAttribute
方法:
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
if (attr != null) {
return attr;
}
}
return null;
}
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
ae, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
// 判断目标方法上是否存在@Transactional注解,如果不存在,则直接返回
AnnotationAttributes attributes = AnnotatedElementUtils
.findMergedAnnotationAttributes(ae, Transactional.class, false, false);
if (attributes != null) {
// 如果目标方法上存在@Transactional注解,则获取注解值,并且封装为TransactionAttribute返回
return parseTransactionAnnotation(attributes);
} else {
return null;
}
}
protected TransactionAttribute parseTransactionAnnotation(
AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
// 获取注解上的propagation值
Propagation propagation = attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
// 获取注解上的isolation属性值
Isolation isolation = attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
// 获取注解上的timeout属性值
rbta.setTimeout(attributes.getNumber("timeout").intValue());
// 获取注解上的readOnly属性值
rbta.setReadOnly(attributes.getBoolean("readOnly"));
// 获取注解上的value属性值
rbta.setQualifier(attributes.getString("value"));
ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<>();
// 获取注解上的rollbackFor属性列表
Class<?>[] rbf = attributes.getClassArray("rollbackFor");
for (Class<?> rbRule : rbf) {
RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
rollBackRules.add(rule);
}
// 获取注解上的rollbackForClassName属性列表
String[] rbfc = attributes.getStringArray("rollbackForClassName");
for (String rbRule : rbfc) {
RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
rollBackRules.add(rule);
}
// 获取注解上的noRollbackFor属性列表
Class<?>[] nrbf = attributes.getClassArray("noRollbackFor");
for (Class<?> rbRule : nrbf) {
NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
rollBackRules.add(rule);
}
// 获取注解上的noRollbackForClassName属性列表
String[] nrbfc = attributes.getStringArray("noRollbackForClassName");
for (String rbRule : nrbfc) {
NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
rollBackRules.add(rule);
}
rbta.getRollbackRules().addAll(rollBackRules);
return rbta;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
可以看到这里已经把方法上或者类上的@Transactional
注解的属性封装成TransactionAttribute
返回了
# 5.3 TransactionInterceptor
代理的实现就是基于这个拦截器
看一下这个拦截器的代码
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
Method var10001 = invocation.getMethod();
invocation.getClass();
return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);
}
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
TransactionAttributeSource tas = this.getTransactionAttributeSource();
// 获取事务属性
TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;
PlatformTransactionManager tm = this.determineTransactionManager(txAttr);
//方法标识,例如usersService.testTransaction
String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);
Object result;
if (txAttr != null && tm instanceof CallbackPreferringPlatformTransactionManager) {
//编程式事务处理
TransactionAspectSupport.ThrowableHolder throwableHolder = new TransactionAspectSupport.ThrowableHolder();
try {
result = ((CallbackPreferringPlatformTransactionManager)tm).execute(txAttr, (status) -> {
// 1.创建TransactionInfo
TransactionAspectSupport.TransactionInfo txInfo = this.prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
Object var9;
try {
// 2. 调用执行链
Object var8 = invocation.proceedWithInvocation();
return var8;
} catch (Throwable var13) {
// 3. 异常回滚
if (txAttr.rollbackOn(var13)) {
if (var13 instanceof RuntimeException) {
throw (RuntimeException)var13;
}
throw new TransactionAspectSupport.ThrowableHolderException(var13);
}
throwableHolder.throwable = var13;
var9 = null;
} finally {
//4. 清除事务信息
this.cleanupTransactionInfo(txInfo);
}
return var9;
});
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
} else {
return result;
}
} catch (TransactionAspectSupport.ThrowableHolderException var19) {
throw var19.getCause();
} catch (TransactionSystemException var20) {
if (throwableHolder.throwable != null) {
this.logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
var20.initApplicationException(throwableHolder.throwable);
}
throw var20;
} catch (Throwable var21) {
if (throwableHolder.throwable != null) {
this.logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw var21;
}
} else {
//声明式事务
TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
result = null;
try {
result = invocation.proceedWithInvocation();
} catch (Throwable var17) {
// 3. 异常回滚
this.completeTransactionAfterThrowing(txInfo, var17);
throw var17;
} finally {
//4. 清除事务信息
this.cleanupTransactionInfo(txInfo);
}
//5 提交事务
this.commitTransactionAfterReturning(txInfo);
return result;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
由于经常使用的就是声明式事务,所以接下来的解析也是基于声明式事务来的:
# 5.3.1、创建事务
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
//如果事务没有指定名称则使用方法标识
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
//1. 创建事务
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
//2.构建事务信息
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 5.3.2、获取事务
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
//1. 获取事务
Object transaction = doGetTransaction();
boolean debugEnabled = logger.isDebugEnabled();
if (definition == null) {
definition = new DefaultTransactionDefinition();
}
//2. 判断当前线程是否存在事务
if (isExistingTransaction(transaction)) {
//存在事务则使用嵌套事务处理
return handleExistingTransaction(definition, transaction, debugEnabled);
}
// 事务超时
if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
}
// 如果当前没有事务,但是事务的传播行为被定义为PROPAGATION_MANDATORY,则抛出异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}//当事务的传播行为需要新建事务时的处理
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
}
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
//3. 准备事务
doBegin(transaction, definition);
//4. 记录事务状态
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
else {
// 创建空事务
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + definition);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
整个获取事务的过程还是包含多个步骤的,其中doBegin比较值得聊一聊:
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try {
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
Connection newCon = obtainDataSource().getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
//获取当前数据库连接
con = txObject.getConnectionHolder().getConnection();
//获取隔离级别
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// 设置自动提交
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
con.setAutoCommit(false);
}
prepareTransactionalConnection(con, definition);
//设置当前线程存在事务的标示
txObject.getConnectionHolder().setTransactionActive(true);
//设置超时时间
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}
// 将连接绑定到当前线程
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
}
}
catch (Throwable ex) {
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, obtainDataSource());
txObject.setConnectionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
至于记录事务状态这里先不说,先看一下已存在的事务是如何处理的:
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
//判断传播行为是否需要存在事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
//不开启事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
//总是新建事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}
//嵌套事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
if (debugEnabled) {
logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
}
if (useSavepointForNestedTransaction()) {
// Create savepoint within existing Spring-managed transaction,
// through the SavepointManager API implemented by TransactionStatus.
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}
else {
// Nested transaction through nested begin and commit/rollback calls.
// Usually only for JTA: Spring synchronization might get activated here
// in case of a pre-existing JTA transaction.
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
}
// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
if (debugEnabled) {
logger.debug("Participating in existing transaction");
}
if (isValidateExistingTransaction()) {
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
Constants isoConstants = DefaultTransactionDefinition.constants;
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] specifies isolation level which is incompatible with existing transaction: " +
(currentIsolationLevel != null ?
isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
"(unknown)"));
}
}
if (!definition.isReadOnly()) {
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] is not marked as read-only but existing transaction is");
}
}
}
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
可以看到记录事务状态是最后一步了:
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
if (status.isNewSynchronization()) {
TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
definition.getIsolationLevel() : null);
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
TransactionSynchronizationManager.initSynchronization();
}
}
2
3
4
5
6
7
8
9
10
11
# 5.3.3、构建事务信息
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, String joinpointIdentification,
@Nullable TransactionStatus status) {
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
if (txAttr != null)
if (logger.isTraceEnabled()) {
logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
// 记录事务状态
txInfo.newTransactionStatus(status);
}
else {
if (logger.isTraceEnabled())
logger.trace("Don't need to create transaction for [" + joinpointIdentification +
"]: This method isn't transactional.");
}
txInfo.bindToThread();
return txInfo;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 5.3.4、事务回滚
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
//是否存在事务
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
}
//是否满足回滚条件,比如是否运行时异常等
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
try {
//回滚处理
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
}
else {
//不满足回滚条件时同样提交
try {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by commit exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by commit exception", ex);
throw ex2;
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
看看回滚的逻辑:
public final void rollback(TransactionStatus status) throws TransactionException {
//如果事务完成了就不能回滚
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
processRollback(defStatus, false);
}
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
try {
boolean unexpectedRollback = unexpected;
try {
//扩展点
triggerBeforeCompletion(status);
//如果有保存点
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
//推到保存点
status.rollbackToHeldSavepoint();
}
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}//如果当前事务为独立事务则直接回退
doRollback(status);
}
else {
// Participating in larger transaction
if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
//不是独立事务标记状态
doSetRollbackOnly(status);
}
else {
if (status.isDebug()) {
logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
}
}
}
else {
logger.debug("Should roll back transaction but cannot - no transaction available");
}
// Unexpected rollback only matters here if we're asked to fail early
if (!isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = false;
}
}
}
catch (RuntimeException | Error ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
//扩展点
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
// Raise UnexpectedRollbackException if we had a global rollback-only marker
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
}
finally {
//清理资源
cleanupAfterCompletion(status);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
而真正的回滚逻辑则是利用JDBC的回滚逻辑实现的:
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
this.logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
}
try {
con.rollback();
} catch (SQLException var5) {
throw new TransactionSystemException("Could not roll back JDBC transaction", var5);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
# 5.3.5、事务提交
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
public final void commit(TransactionStatus status) throws TransactionException {
//如果事务已经完成
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
//如果事务设置了回滚标记则直接回滚
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
processRollback(defStatus, false);
return;
}
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
processRollback(defStatus, true);
return;
}
//提交事务
processCommit(defStatus);
}
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
boolean unexpectedRollback = false;
//扩展点的相关调用
prepareForCommit(status);
triggerBeforeCommit(status);
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
unexpectedRollback = status.isGlobalRollbackOnly();
//清除保存点信息
status.releaseHeldSavepoint();
}
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
unexpectedRollback = status.isGlobalRollbackOnly();
//提交事务,同样这里也是调用的JDBC的方法实现的
doCommit(status);
}
else if (isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = status.isGlobalRollbackOnly();
}
// Throw UnexpectedRollbackException if we have a global rollback-only
// marker but still didn't get a corresponding exception from commit.
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
// can only be caused by doCommit
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
catch (TransactionException ex) {
// can only be caused by doCommit
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(status, ex);
}
else {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
catch (RuntimeException | Error ex) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
doRollbackOnCommitException(status, ex);
throw ex;
}
// Trigger afterCommit callbacks, with an exception thrown there
// propagated to callers but the transaction still considered as committed.
try {
triggerAfterCommit(status);
}
finally {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}
}
finally {
cleanupAfterCompletion(status);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# 6、SpringMVC源码解析
为什么在SpringBoot中使用SpringMVC的时候是不需要像传统Spring中配置web.xml和配置文件
主要是因为这个类
WebMvcAutoConfiguration
# 6.1、WebMvcAutoConfiguration
@Configuration
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
public static final String DEFAULT_PREFIX = "";
public static final String DEFAULT_SUFFIX = "";
private static final String[] SERVLET_LOCATIONS = new String[]{"/"};
public WebMvcAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
@Bean
@ConditionalOnMissingBean({HttpPutFormContentFilter.class})
@ConditionalOnProperty(
prefix = "spring.mvc.formcontent.putfilter",
name = {"enabled"},
matchIfMissing = true
)
public OrderedHttpPutFormContentFilter httpPutFormContentFilter() {
return new OrderedHttpPutFormContentFilter();
}
static class OptionalPathExtensionContentNegotiationStrategy implements ContentNegotiationStrategy {
private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class.getName() + ".SKIP";
private final ContentNegotiationStrategy delegate;
OptionalPathExtensionContentNegotiationStrategy(ContentNegotiationStrategy delegate) {
this.delegate = delegate;
}
public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException {
Object skip = webRequest.getAttribute(SKIP_ATTRIBUTE, 0);
return skip != null && Boolean.parseBoolean(skip.toString()) ? Collections.emptyList() : this.delegate.resolveMediaTypes(webRequest);
}
}
private static class ResourceChainResourceHandlerRegistrationCustomizer implements WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer {
@Autowired
private ResourceProperties resourceProperties;
private ResourceChainResourceHandlerRegistrationCustomizer() {
this.resourceProperties = new ResourceProperties();
}
public void customize(ResourceHandlerRegistration registration) {
Chain properties = this.resourceProperties.getChain();
this.configureResourceChain(properties, registration.resourceChain(properties.isCache()));
}
private void configureResourceChain(Chain properties, ResourceChainRegistration chain) {
Strategy strategy = properties.getStrategy();
if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) {
chain.addResolver(this.getVersionResourceResolver(strategy));
}
if (properties.isGzipped()) {
chain.addResolver(new GzipResourceResolver());
}
if (properties.isHtmlApplicationCache()) {
chain.addTransformer(new AppCacheManifestTransformer());
}
}
private ResourceResolver getVersionResourceResolver(Strategy properties) {
VersionResourceResolver resolver = new VersionResourceResolver();
if (properties.getFixed().isEnabled()) {
String version = properties.getFixed().getVersion();
String[] paths = properties.getFixed().getPaths();
resolver.addFixedVersionStrategy(version, paths);
}
if (properties.getContent().isEnabled()) {
String[] paths = properties.getContent().getPaths();
resolver.addContentVersionStrategy(paths);
}
return resolver;
}
}
interface ResourceHandlerRegistrationCustomizer {
void customize(ResourceHandlerRegistration registration);
}
@Configuration
@ConditionalOnEnabledResourceChain
static class ResourceChainCustomizerConfiguration {
ResourceChainCustomizerConfiguration() {
}
@Bean
public WebMvcAutoConfiguration.ResourceChainResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer() {
return new WebMvcAutoConfiguration.ResourceChainResourceHandlerRegistrationCustomizer();
}
}
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
private final WebMvcProperties mvcProperties;
private final ListableBeanFactory beanFactory;
private final WebMvcRegistrations mvcRegistrations;
public EnableWebMvcConfiguration(ObjectProvider<WebMvcProperties> mvcPropertiesProvider, ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider, ListableBeanFactory beanFactory) {
this.mvcProperties = (WebMvcProperties)mvcPropertiesProvider.getIfAvailable();
this.mvcRegistrations = (WebMvcRegistrations)mvcRegistrationsProvider.getIfUnique();
this.beanFactory = beanFactory;
}
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties == null || this.mvcProperties.isIgnoreDefaultModelOnRedirect());
return adapter;
}
protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
return this.mvcRegistrations != null && this.mvcRegistrations.getRequestMappingHandlerAdapter() != null ? this.mvcRegistrations.getRequestMappingHandlerAdapter() : super.createRequestMappingHandlerAdapter();
}
@Bean
@Primary
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return super.requestMappingHandlerMapping();
}
@Bean
public FormattingConversionService mvcConversionService() {
WebConversionService conversionService = new WebConversionService(this.mvcProperties.getDateFormat());
this.addFormatters(conversionService);
return conversionService;
}
@Bean
public Validator mvcValidator() {
return !ClassUtils.isPresent("javax.validation.Validator", this.getClass().getClassLoader()) ? super.mvcValidator() : ValidatorAdapter.get(this.getApplicationContext(), this.getValidator());
}
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
return this.mvcRegistrations != null && this.mvcRegistrations.getRequestMappingHandlerMapping() != null ? this.mvcRegistrations.getRequestMappingHandlerMapping() : super.createRequestMappingHandlerMapping();
}
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
try {
return (ConfigurableWebBindingInitializer)this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
} catch (NoSuchBeanDefinitionException var2) {
return super.getConfigurableWebBindingInitializer();
}
}
protected ExceptionHandlerExceptionResolver createExceptionHandlerExceptionResolver() {
return this.mvcRegistrations != null && this.mvcRegistrations.getExceptionHandlerExceptionResolver() != null ? this.mvcRegistrations.getExceptionHandlerExceptionResolver() : super.createExceptionHandlerExceptionResolver();
}
protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
super.configureHandlerExceptionResolvers(exceptionResolvers);
if (exceptionResolvers.isEmpty()) {
this.addDefaultHandlerExceptionResolvers(exceptionResolvers);
}
if (this.mvcProperties.isLogResolvedException()) {
Iterator var2 = exceptionResolvers.iterator();
while(var2.hasNext()) {
HandlerExceptionResolver resolver = (HandlerExceptionResolver)var2.next();
if (resolver instanceof AbstractHandlerExceptionResolver) {
((AbstractHandlerExceptionResolver)resolver).setWarnLogCategory(resolver.getClass().getName());
}
}
}
}
@Bean
public ContentNegotiationManager mvcContentNegotiationManager() {
ContentNegotiationManager manager = super.mvcContentNegotiationManager();
List<ContentNegotiationStrategy> strategies = manager.getStrategies();
ListIterator iterator = strategies.listIterator();
while(iterator.hasNext()) {
ContentNegotiationStrategy strategy = (ContentNegotiationStrategy)iterator.next();
if (strategy instanceof PathExtensionContentNegotiationStrategy) {
iterator.set(new WebMvcAutoConfiguration.OptionalPathExtensionContentNegotiationStrategy(strategy));
}
}
return manager;
}
}
@Configuration
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware {
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
private final ResourceProperties resourceProperties;
private final WebMvcProperties mvcProperties;
private final ListableBeanFactory beanFactory;
private final HttpMessageConverters messageConverters;
final WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
private ResourceLoader resourceLoader;
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, @Lazy HttpMessageConverters messageConverters, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
this.resourceProperties = resourceProperties;
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConverters = messageConverters;
this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.addAll(this.messageConverters.getConverters());
}
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
Duration timeout = this.mvcProperties.getAsync().getRequestTimeout();
if (timeout != null) {
configurer.setDefaultTimeout(timeout.toMillis());
}
}
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(this.mvcProperties.getPathmatch().isUseSuffixPattern());
configurer.setUseRegisteredSuffixPatternMatch(this.mvcProperties.getPathmatch().isUseRegisteredSuffixPattern());
}
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
Contentnegotiation contentnegotiation = this.mvcProperties.getContentnegotiation();
configurer.favorPathExtension(contentnegotiation.isFavorPathExtension());
configurer.favorParameter(contentnegotiation.isFavorParameter());
if (contentnegotiation.getParameterName() != null) {
configurer.parameterName(contentnegotiation.getParameterName());
}
Map<String, MediaType> mediaTypes = this.mvcProperties.getContentnegotiation().getMediaTypes();
Iterator var4 = mediaTypes.entrySet().iterator();
while(var4.hasNext()) {
Entry<String, MediaType> mediaType = (Entry)var4.next();
configurer.mediaType((String)mediaType.getKey(), (MediaType)mediaType.getValue());
}
}
@Bean
@ConditionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(this.mvcProperties.getView().getPrefix());
resolver.setSuffix(this.mvcProperties.getView().getSuffix());
return resolver;
}
@Bean
@ConditionalOnBean({View.class})
@ConditionalOnMissingBean
public BeanNameViewResolver beanNameViewResolver() {
BeanNameViewResolver resolver = new BeanNameViewResolver();
resolver.setOrder(2147483637);
return resolver;
}
@Bean
@ConditionalOnBean({ViewResolver.class})
@ConditionalOnMissingBean(
name = {"viewResolver"},
value = {ContentNegotiatingViewResolver.class}
)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
resolver.setOrder(-2147483648);
return resolver;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(
prefix = "spring.mvc",
name = {"locale"}
)
public LocaleResolver localeResolver() {
if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
} else {
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
}
public MessageCodesResolver getMessageCodesResolver() {
if (this.mvcProperties.getMessageCodesResolverFormat() != null) {
DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver();
resolver.setMessageCodeFormatter(this.mvcProperties.getMessageCodesResolverFormat());
return resolver;
} else {
return null;
}
}
public void addFormatters(FormatterRegistry registry) {
Iterator var2 = this.getBeansOfType(Converter.class).iterator();
while(var2.hasNext()) {
Converter<?, ?> converter = (Converter)var2.next();
registry.addConverter(converter);
}
var2 = this.getBeansOfType(GenericConverter.class).iterator();
while(var2.hasNext()) {
GenericConverter converter = (GenericConverter)var2.next();
registry.addConverter(converter);
}
var2 = this.getBeansOfType(Formatter.class).iterator();
while(var2.hasNext()) {
Formatter<?> formatter = (Formatter)var2.next();
registry.addFormatter(formatter);
}
}
private <T> Collection<T> getBeansOfType(Class<T> type) {
return this.beanFactory.getBeansOfType(type).values();
}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
}
private Integer getSeconds(Duration cachePeriod) {
return cachePeriod == null ? null : (int)cachePeriod.getSeconds();
}
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
return new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
}
static String[] getResourceLocations(String[] staticLocations) {
String[] locations = new String[staticLocations.length + WebMvcAutoConfiguration.SERVLET_LOCATIONS.length];
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
System.arraycopy(WebMvcAutoConfiguration.SERVLET_LOCATIONS, 0, locations, staticLocations.length, WebMvcAutoConfiguration.SERVLET_LOCATIONS.length);
return locations;
}
private Optional<Resource> getWelcomePage() {
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
private boolean isReadable(Resource resource) {
try {
return resource.exists() && resource.getURL() != null;
} catch (Exception var3) {
return false;
}
}
private void customizeResourceHandlerRegistration(ResourceHandlerRegistration registration) {
if (this.resourceHandlerRegistrationCustomizer != null) {
this.resourceHandlerRegistrationCustomizer.customize(registration);
}
}
@Bean
@ConditionalOnMissingBean({RequestContextListener.class, RequestContextFilter.class})
public static RequestContextFilter requestContextFilter() {
return new OrderedRequestContextFilter();
}
@Configuration
@ConditionalOnProperty(
value = {"spring.mvc.favicon.enabled"},
matchIfMissing = true
)
public static class FaviconConfiguration implements ResourceLoaderAware {
private final ResourceProperties resourceProperties;
private ResourceLoader resourceLoader;
public FaviconConfiguration(ResourceProperties resourceProperties) {
this.resourceProperties = resourceProperties;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(-2147483647);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", this.faviconRequestHandler()));
return mapping;
}
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler.setLocations(this.resolveFaviconLocations());
return requestHandler;
}
private List<Resource> resolveFaviconLocations() {
String[] staticLocations = WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.getResourceLocations(this.resourceProperties.getStaticLocations());
List<Resource> locations = new ArrayList(staticLocations.length + 1);
Stream var10000 = Arrays.stream(staticLocations);
ResourceLoader var10001 = this.resourceLoader;
var10001.getClass();
var10000.map(var10001::getResource).forEach(locations::add);
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# 6.2、DispatcherServlet
DispatcherServlet
是一个实现了Servlet
接口的类,Servlet
的初始化阶段会调用它的init()
方法,而DispatcherServlet
的方法是继承自父类HttpServletBean
的
# 6.2.1、HttpServletBean#init()
public final void init() throws ServletException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Initializing servlet '" + this.getServletName() + "'");
}
//处理init-param参数,但是SpringBoot中默认是没有的
PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
if (!pvs.isEmpty()) {
try {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
this.initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
} catch (BeansException var4) {
if (this.logger.isErrorEnabled()) {
this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
}
throw var4;
}
}
// 初始化Servlet,往下看
this.initServletBean();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Servlet '" + this.getServletName() + "' configured successfully");
}
}
protected final void initServletBean() throws ServletException {
this.getServletContext().log("Initializing Spring FrameworkServlet '" + this.getServletName() + "'");
if (this.logger.isInfoEnabled()) {
this.logger.info("FrameworkServlet '" + this.getServletName() + "': initialization started");
}
long startTime = System.currentTimeMillis();
try {
//初始化web容器 ->
this.webApplicationContext = this.initWebApplicationContext();
//扩展点
this.initFrameworkServlet();
} catch (ServletException var5) {
this.logger.error("Context initialization failed", var5);
throw var5;
} catch (RuntimeException var6) {
this.logger.error("Context initialization failed", var6);
throw var6;
}
if (this.logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
this.logger.info("FrameworkServlet '" + this.getServletName() + "': initialization completed in " + elapsedTime + " ms");
}
}
//初始化web容器
protected WebApplicationContext initWebApplicationContext() {
//获取AnnotationConfigServletWebServerApplicationContext类型的web容器
WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
WebApplicationContext wac = null;
if (this.webApplicationContext != null) {
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac;
if (!cwac.isActive()) {
if (cwac.getParent() == null) {
cwac.setParent(rootContext);
}
this.configureAndRefreshWebApplicationContext(cwac);
}
}
}
if (wac == null) {
wac = this.findWebApplicationContext();
}
if (wac == null) {
wac = this.createWebApplicationContext(rootContext);
}
if (!this.refreshEventReceived) {
// 刷新应用上下文,这里是重点,接着往下看
this.onRefresh(wac);
}
if (this.publishContext) {
// 推送事件通知
String attrName = this.getServletContextAttributeName();
this.getServletContext().setAttribute(attrName, wac);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Published WebApplicationContext of servlet '" + this.getServletName() + "' as ServletContext attribute with name [" + attrName + "]");
}
}
return wac;
}
protected void onRefresh(ApplicationContext context) {
this.initStrategies(context);
}
//常用组件的初始化
protected void initStrategies(ApplicationContext context) {
this.initMultipartResolver(context);
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# 6.3、SpringMVC的处理流程
在日常开发中,我们最常用的请求方式大概就是Get和Post了,Tomcat或者Jetty等web服务器在接受到请求后会调用到
DispatcherServlet
对应的方法
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.processRequest(request, response);
}
protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.processRequest(request, response);
}
protected final void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
long startTime = System.currentTimeMillis();
Throwable failureCause = null;
//记录当前线程的信息
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = this.buildLocaleContext(request);
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = this.buildRequestAttributes(request, response, previousAttributes);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new FrameworkServlet.RequestBindingInterceptor());
this.initContextHolders(request, localeContext, requestAttributes);
try {
//核心处理,往下看
this.doService(request, response);
} catch (IOException | ServletException var16) {
failureCause = var16;
throw var16;
} catch (Throwable var17) {
failureCause = var17;
throw new NestedServletException("Request processing failed", var17);
} finally {
//清除线程绑定信息
this.resetContextHolders(request, previousLocaleContext, previousAttributes);
if (requestAttributes != null) {
requestAttributes.requestCompleted();
}
if (this.logger.isDebugEnabled()) {
if (failureCause != null) {
this.logger.debug("Could not complete request", (Throwable)failureCause);
} else if (asyncManager.isConcurrentHandlingStarted()) {
this.logger.debug("Leaving response open for concurrent processing");
} else {
this.logger.debug("Successfully completed request");
}
}
//发送事件通知
this.publishRequestHandledEvent(request, response, startTime, (Throwable)failureCause);
}
}
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (this.logger.isDebugEnabled()) {
String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
this.logger.debug("DispatcherServlet with name '" + this.getServletName() + "'" + resumed + " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");
}
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap();
Enumeration attrNames = request.getAttributeNames();
label112:
while(true) {
String attrName;
do {
if (!attrNames.hasMoreElements()) {
break label112;
}
attrName = (String)attrNames.nextElement();
} while(!this.cleanupAfterInclude && !attrName.startsWith("org.springframework.web.servlet"));
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, this.getThemeSource());
if (this.flashMapManager != null) {
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
}
try {
//核心逻辑
this.doDispatch(request, response);
} finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) {
this.restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
//如果是文件上传请求则进行特殊处理
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// 1.获取对应的handler
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
//如果没有获取到对应的handler则往response中写入错误信息
this.noHandlerFound(processedRequest, response);
return;
}
// 2. 获取对应的handlerAdapter
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
// 处理last-modified情况
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (this.logger.isDebugEnabled()) {
this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 3.调用handle
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//如果函数调用没有返回视图则使用默认的
this.applyDefaultViewName(processedRequest, mv);
//执行拦截器
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
//4. 处理返回结果
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
} catch (Exception var22) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# 6.3.1、获取Handler
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
Iterator var2 = this.handlerMappings.iterator();
//遍历所有的handlerMapping,这里的handlemapping就是初始化阶段构造的三个
while(var2.hasNext()) {
HandlerMapping hm = (HandlerMapping)var2.next();
if (this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + this.getServletName() + "'");
}
//这里调用具体的handler,哪个handler能够处理就直接返回
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//1. 调用具体的实现去获取handler
Object handler = this.getHandlerInternal(request);
if (handler == null) {
//如果为空使用默认的
handler = this.getDefaultHandler();
}
if (handler == null) {
//没有默认的返回空
return null;
} else {
// 尝试通过BeanName去获取handler
if (handler instanceof String) {
String handlerName = (String)handler;
handler = this.obtainApplicationContext().getBean(handlerName);
}
//2. 获取handler执行链
HandlerExecutionChain executionChain = this.getHandlerExecutionChain(handler, request);
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = this.getCorsConfiguration(handler, request);
CorsConfiguration config = globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig;
executionChain = this.getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
1. 获取具体的handler:
这里以
AbstractUrlHandlerMapping
为例解读一下,顾明思议,这个类是根据请求url获取响应的handler的
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
//截取url
String lookupPath = this.getUrlPathHelper().getLookupPathForRequest(request);
//根据url寻找handler
Object handler = this.lookupHandler(lookupPath, request);
if (handler == null) {
Object rawHandler = null;
if ("/".equals(lookupPath)) {
// 如果请求路径为/则使用RootHandler
rawHandler = this.getRootHandler();
}
if (rawHandler == null) {
//使用默认
rawHandler = this.getDefaultHandler();
}
if (rawHandler != null) {
if (rawHandler instanceof String) {
String handlerName = (String)rawHandler;
// 根据beanName尝试获取Handler
rawHandler = this.obtainApplicationContext().getBean(handlerName);
}
//校验
this.validateHandler(rawHandler, request);
handler = this.buildPathExposingHandler(rawHandler, lookupPath, lookupPath, (Map)null);
}
}
if (handler != null && this.logger.isDebugEnabled()) {
this.logger.debug("Mapping [" + lookupPath + "] to " + handler);
} else if (handler == null && this.logger.isTraceEnabled()) {
this.logger.trace("No handler mapping found for [" + lookupPath + "]");
}
return handler;
}
protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
// 直接根据url匹配
Object handler = this.handlerMap.get(urlPath);
if (handler != null) {
if (handler instanceof String) {
String handlerName = (String)handler;
handler = this.obtainApplicationContext().getBean(handlerName);
}
this.validateHandler(handler, request);
//封装执行链
return this.buildPathExposingHandler(handler, urlPath, urlPath, (Map)null);
} else {
// 正则匹配
List<String> matchingPatterns = new ArrayList();
Iterator var5 = this.handlerMap.keySet().iterator();
while(var5.hasNext()) {
String registeredPattern = (String)var5.next();
if (this.getPathMatcher().match(registeredPattern, urlPath)) {
matchingPatterns.add(registeredPattern);
} else if (this.useTrailingSlashMatch() && !registeredPattern.endsWith("/") && this.getPathMatcher().match(registeredPattern + "/", urlPath)) {
matchingPatterns.add(registeredPattern + "/");
}
}
String bestMatch = null;
Comparator<String> patternComparator = this.getPathMatcher().getPatternComparator(urlPath);
if (!matchingPatterns.isEmpty()) {
matchingPatterns.sort(patternComparator);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);
}
bestMatch = (String)matchingPatterns.get(0);
}
if (bestMatch != null) {
handler = this.handlerMap.get(bestMatch);
if (handler == null) {
if (bestMatch.endsWith("/")) {
handler = this.handlerMap.get(bestMatch.substring(0, bestMatch.length() - 1));
}
if (handler == null) {
throw new IllegalStateException("Could not find handler for best pattern match [" + bestMatch + "]");
}
}
String pathWithinMapping;
if (handler instanceof String) {
pathWithinMapping = (String)handler;
handler = this.obtainApplicationContext().getBean(pathWithinMapping);
}
this.validateHandler(handler, request);
pathWithinMapping = this.getPathMatcher().extractPathWithinPattern(bestMatch, urlPath);
Map<String, String> uriTemplateVariables = new LinkedHashMap();
Iterator var9 = matchingPatterns.iterator();
while(var9.hasNext()) {
String matchingPattern = (String)var9.next();
if (patternComparator.compare(bestMatch, matchingPattern) == 0) {
Map<String, String> vars = this.getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);
Map<String, String> decodedVars = this.getUrlPathHelper().decodePathVariables(request, vars);
uriTemplateVariables.putAll(decodedVars);
}
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);
}
//当获取到相应的handler后,查看是否存在拦截器,如果存在的话则加入执行链中 ->
return this.buildPathExposingHandler(handler, bestMatch, pathWithinMapping, uriTemplateVariables);
} else {
return null;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
2. 封装执行链
当获取到相应的handler后,查看是否存在拦截器,如果存在的话则加入执行链中
protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern, String pathWithinMapping, @Nullable Map<String, String> uriTemplateVariables) {
HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler);
chain.addInterceptor(new AbstractUrlHandlerMapping.PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping));
if (!CollectionUtils.isEmpty(uriTemplateVariables)) {
chain.addInterceptor(new AbstractUrlHandlerMapping.UriTemplateVariablesHandlerInterceptor(uriTemplateVariables));
}
return chain;
}
2
3
4
5
6
7
8
9
# 6.3.2 、获取HandlerAdpter
根据handler获取匹配的handlerAdpter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
Iterator var2 = this.handlerAdapters.iterator();
while(var2.hasNext()) {
HandlerAdapter ha = (HandlerAdapter)var2.next();
if (this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler adapter [" + ha + "]");
}
//不同的handlerAdapter的判断方法不同
if (ha.supports(handler)) {
return ha;
}
}
}
throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
//以SimpleControllerHandlerAdapter为例,判断是否实现Controller接口
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 6.3.3、执行请求
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return this.handleInternal(request, response, (HandlerMethod)handler);
}
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
this.checkRequest(request);
ModelAndView mav;
// 如果需要同步session
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized(mutex) {
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
} else {
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
} else {
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader("Cache-Control")) {
if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
} else {
this.prepareResponse(response);
}
}
return mav;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 6.3.4、处理返回结果
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
boolean errorView = false;
//是否包含异常信息
if (exception != null) {
if (exception instanceof ModelAndViewDefiningException) {
this.logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException)exception).getModelAndView();
} else {
//异常视图处理
Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
mv = this.processHandlerException(request, response, handler, exception);
errorView = mv != null;
}
}
if (mv != null && !mv.wasCleared()) {
// 页面跳转处理 ->
this.render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + this.getServletName() + "': assuming HandlerAdapter completed request handling");
}
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
}
}
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
Locale locale = this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale();
response.setLocale(locale);
String viewName = mv.getViewName();
View view;
if (viewName != null) {
//1.解析视图名 ->
view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request);
if (view == null) {
throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + this.getServletName() + "'");
}
} else {
view = mv.getView();
if (view == null) {
throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a View object in servlet with name '" + this.getServletName() + "'");
}
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + this.getServletName() + "'");
}
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
//2.跳转
view.render(mv.getModelInternal(), request, response);
} catch (Exception var8) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" + this.getServletName() + "'", var8);
}
throw var8;
}
}
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model, Locale locale, HttpServletRequest request) throws Exception {
if (this.viewResolvers != null) {
Iterator var5 = this.viewResolvers.iterator();
while(var5.hasNext()) {
ViewResolver viewResolver = (ViewResolver)var5.next();
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
return null;
}
//页面跳转根据当前使用的渲染引擎决定的,比如html、jsp、Thymeleaf等,这里简单 列举一个Thymeleaf的逻辑
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
this.renderFragment(this.markupSelectors, model, request, response);
}
protected void renderFragment(Set<String> markupSelectorsToRender, Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
ServletContext servletContext = this.getServletContext();
String viewTemplateName = this.getTemplateName();
ISpringTemplateEngine viewTemplateEngine = this.getTemplateEngine();
if (viewTemplateName == null) {
throw new IllegalArgumentException("Property 'templateName' is required");
} else if (this.getLocale() == null) {
throw new IllegalArgumentException("Property 'locale' is required");
} else if (viewTemplateEngine == null) {
throw new IllegalArgumentException("Property 'templateEngine' is required");
} else {
Map<String, Object> mergedModel = new HashMap(30);
Map<String, Object> templateStaticVariables = this.getStaticVariables();
if (templateStaticVariables != null) {
mergedModel.putAll(templateStaticVariables);
}
if (pathVariablesSelector != null) {
Map<String, Object> pathVars = (Map)request.getAttribute(pathVariablesSelector);
if (pathVars != null) {
mergedModel.putAll(pathVars);
}
}
if (model != null) {
mergedModel.putAll(model);
}
ApplicationContext applicationContext = this.getApplicationContext();
RequestContext requestContext = new RequestContext(request, response, this.getServletContext(), mergedModel);
SpringWebMvcThymeleafRequestContext thymeleafRequestContext = new SpringWebMvcThymeleafRequestContext(requestContext, request);
addRequestContextAsVariable(mergedModel, "springRequestContext", requestContext);
addRequestContextAsVariable(mergedModel, "springMacroRequestContext", requestContext);
mergedModel.put("thymeleafRequestContext", thymeleafRequestContext);
ConversionService conversionService = (ConversionService)request.getAttribute(ConversionService.class.getName());
ThymeleafEvaluationContext evaluationContext = new ThymeleafEvaluationContext(applicationContext, conversionService);
mergedModel.put("thymeleaf::EvaluationContext", evaluationContext);
IEngineConfiguration configuration = viewTemplateEngine.getConfiguration();
WebExpressionContext context = new WebExpressionContext(configuration, request, response, servletContext, this.getLocale(), mergedModel);
String templateName;
Set markupSelectors;
if (!viewTemplateName.contains("::")) {
templateName = viewTemplateName;
markupSelectors = null;
} else {
IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
FragmentExpression fragmentExpression;
try {
fragmentExpression = (FragmentExpression)parser.parseExpression(context, "~{" + viewTemplateName + "}");
} catch (TemplateProcessingException var24) {
throw new IllegalArgumentException("Invalid template name specification: '" + viewTemplateName + "'");
}
ExecutedFragmentExpression fragment = FragmentExpression.createExecutedFragmentExpression(context, fragmentExpression);
templateName = FragmentExpression.resolveTemplateName(fragment);
markupSelectors = FragmentExpression.resolveFragments(fragment);
Map<String, Object> nameFragmentParameters = fragment.getFragmentParameters();
if (nameFragmentParameters != null) {
if (fragment.hasSyntheticParameters()) {
throw new IllegalArgumentException("Parameters in a view specification must be named (non-synthetic): '" + viewTemplateName + "'");
}
context.setVariables(nameFragmentParameters);
}
}
String templateContentType = this.getContentType();
Locale templateLocale = this.getLocale();
String templateCharacterEncoding = this.getCharacterEncoding();
Set processMarkupSelectors;
if (markupSelectors != null && markupSelectors.size() > 0) {
if (markupSelectorsToRender != null && markupSelectorsToRender.size() > 0) {
throw new IllegalArgumentException("A markup selector has been specified (" + Arrays.asList(markupSelectors) + ") for a view that was already being executed as a fragment (" + Arrays.asList(markupSelectorsToRender) + "). Only one fragment selection is allowed.");
}
processMarkupSelectors = markupSelectors;
} else if (markupSelectorsToRender != null && markupSelectorsToRender.size() > 0) {
processMarkupSelectors = markupSelectorsToRender;
} else {
processMarkupSelectors = null;
}
response.setLocale(templateLocale);
if (!this.getForceContentType()) {
String computedContentType = SpringContentTypeUtils.computeViewContentType(request, templateContentType != null ? templateContentType : "text/html;charset=ISO-8859-1", templateCharacterEncoding != null ? Charset.forName(templateCharacterEncoding) : null);
response.setContentType(computedContentType);
} else {
if (templateContentType != null) {
response.setContentType(templateContentType);
} else {
response.setContentType("text/html;charset=ISO-8859-1");
}
if (templateCharacterEncoding != null) {
response.setCharacterEncoding(templateCharacterEncoding);
}
}
viewTemplateEngine.process(templateName, processMarkupSelectors, context, response.getWriter());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194