Merge pull request #20 from huifer/master

source code
pull/21/head
AmyliaY 6 years ago committed by GitHub
commit 709e59cf5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -19,6 +19,7 @@
### AOP
- [AOP 源码实现及分析](/docs/Spring/AOP/AOP源码实现及分析.md)
- [JDK 动态代理的实现原理解析](/docs/Spring/AOP/JDK动态代理的实现原理解析.md)
- [Spring AOP 如何生效(Spring AOP标签解析)](/docs/Spring/AOP/Spring-Aop如何生效.md)
### SpringMVC
- [温习一下servlet](/docs/Spring/SpringMVC/温习一下servlet.md)
@ -37,6 +38,17 @@
### Spring源码故事瞎编版
- [面筋哥 IoC 容器的一天(上)](/docs/Spring/Spring源码故事瞎编版/面筋哥IoC容器的一天(上).md)
### Spring 类解析
- [Spring 自定义标签解析](/docs/Spring/clazz/Spring-自定义标签解析.md)
- [Spring Scan 包扫描](/docs/Spring/clazz/Spring-scan.md)
- [Spring 注解工具类](/docs/Spring/clazz/Spring-AnnotationUtils.md)
- [Spring 别名注册](/docs/Spring/clazz/Spring-SimpleAliasRegistry.md)
- [Spring 标签解析类](/docs/Spring/clazz/Spring-BeanDefinitionParserDelegate.md)
### Spring5 新特性
- [Spring5-spring.components解析](/docs/Spring/Spring5新特性/Spring-spring-components.md)
## MyBatis
### 基础支持层
- [反射工具箱和TypeHandler系列](docs/Mybatis/基础支持层/1、反射工具箱和TypeHandler系列.md)
@ -50,6 +62,23 @@
- [StatementHandler](docs/Mybatis/核心处理层/4、StatementHandler.md)
- [Executor组件](docs/Mybatis/核心处理层/5、Executor组件.md)
- [SqlSession组件](docs/Mybatis/核心处理层/6、SqlSession组件.md)
### 类解析
- [Mybatis-Cache](/docs/Mybatis/基础支持层/Mybatis-Cache.md)
- [Mybatis-log](/docs/Mybatis/基础支持层/Mybatis-log.md)
- [Mybatis-Reflector](/docs/Mybatis/基础支持层/Mybatis-Reflector.md)
- [Mybatis-Alias](/docs/Mybatis/核心处理层/Mybatis-Alias.md)
- [Mybatis-Cursor](/docs/Mybatis/核心处理层/Mybatis-Cursor.md)
- [Mybatis-DataSource](/docs/Mybatis/核心处理层/Mybatis-DataSource.md)
- [Mybatis-DyanmicSqlSourcce](/docs/Mybatis/核心处理层/Mybatis-DyanmicSqlSourcce.md)
- [Mybatis-MapperMethod](/docs/Mybatis/核心处理层/Mybatis-MapperMethod.md)
- [Mybatis-MetaObject](/docs/Mybatis/核心处理层/Mybatis-MetaObject.md)
- [Mybatis-MethodSignature](/docs/Mybatis/核心处理层/Mybatis-MethodSignature.md)
- [Mybatis-ObjectWrapper](/docs/Mybatis/核心处理层/Mybatis-ObjectWrapper.md)
- [Mybatis-ParamNameResolver](/docs/Mybatis/核心处理层/Mybatis-ParamNameResolver.md)
- [Mybatis-SqlCommand](/docs/Mybatis/核心处理层/Mybatis-SqlCommand.md)
- [Mybats-GenericTokenParser](/docs/Mybatis/核心处理层/Mybats-GenericTokenParser.md)
## Netty
### IO
- [把被说烂的BIO、NIO、AIO再从头到尾扯一遍](docs/Netty/IO/把被说烂的BIO、NIO、AIO再从头到尾扯一遍.md)

@ -0,0 +1,141 @@
# Spring AOP 如何生效
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
## 解析
- 在使用 Spring AOP 技术的时候会有下面这段代码在xml配置文件中出现,来达到 Spring 支持 AOP
```xml
<aop:aspectj-autoproxy/>
```
- 源码阅读目标找到了,那么怎么去找入口或者对这句话的标签解析方法呢?项目中使用搜索
![image-20200115083744268](/images/spring/image-20200115083744268.png)
这样就找到了具体解析方法了
### `org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser`
- 类图
![image-20200115084031725](/images/spring/image-20200115084031725.png)
```java
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 注册 <aop:aspectj-autoproxy/>
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
// 子类解析
extendBeanDefinition(element, parserContext);
return null;
}
```
```java
/**
* 注册 <aop:aspectj-autoproxy/>
* @param parserContext
* @param sourceElement
*/
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
// 注册或者升级bean
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
// proxy-target-class 和 expose-proxy 标签处理
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
// 注册组件并且交给监听器
registerComponentIfNecessary(beanDefinition, parserContext);
}
```
- `org.springframework.aop.config.AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)`
```java
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 注册或者升级 AspectJ
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
```
- `org.springframework.aop.config.AopConfigUtils.registerOrEscalateApcAsRequired`
```java
/**
* 注册或者升级 bean
* @param cls 类
* @param registry 注册器
* @param source 源类
* @return
*/
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 判断注册器是否包含org.springframework.aop.config.internalAutoProxyCreator
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
// 获取注册器
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
// 创建新的bean对象
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
// 即将创建的Bean对象和当前的注册器相同返回null
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
// 设置加载顺序
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册bean定义
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
```
### org.springframework.aop.config.AopNamespaceUtils.useClassProxyingIfNecessary
```java
/**
* proxy-target-class 和 expose-proxy 标签处理
*/
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
if (sourceElement != null) {
// 处理 proxy-target-class
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
// 处理 expose-proxy
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
```
- `org.springframework.aop.config.AopConfigUtils.forceAutoProxyCreatorToUseClassProxying`
```java
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
```
- `forceAutoProxyCreatorToExposeProxy`方法就不贴出代码了,操作和`forceAutoProxyCreatorToUseClassProxying`一样都是将读取到的数据放入bean对象作为一个属性存储
## 总结
- 实现`org.springframework.beans.factory.xml.BeanDefinitionParser`接口的类,多用于对xml标签的解析,并且入口为`parse`方法,如果是一个bean对象通常会和Spring监听器一起出现

@ -0,0 +1,658 @@
# Spring 自定义标签解析
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework)
- 与自定义标签解析相关的类
1. `org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser`
2. `org.springframework.beans.factory.xml.NamespaceHandlerSupport`
- 开始源码之前先搭建一个环境
## 环境搭建
- 创建对象
```java
public class UserXtd {
private String userName;
private String emailAddress;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
}
```
- 创建 xsd 文件
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.huifer.com/schema/user"
elementFormDefault="qualified">
<element name="myUser">
<complexType>
<attribute name="id" type="string"/>
<attribute name="userName" type="string"/>
<attribute name="emailAddress" type="string"/>
</complexType>
</element>
</schema>
```
- 创建 namespaceHandler
```java
public class UserNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("myUser", new UserBeanDefinitionParser());
}
}
```
- 创建 beanDefinitionParser
```java
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
/**
* 标签对应class
* @param element the {@code Element} that is being parsed
* @return
*/
@Override
protected Class<?> getBeanClass(Element element) {
return UserXtd.class;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
// 获取 userName 标签属性值
String name = element.getAttribute("userName");
// 获取 emailAddress 标签属性值
String address = element.getAttribute("emailAddress");
if (StringUtils.hasText(name)) {
builder.addPropertyValue("userName", name);
}
if (StringUtils.hasText(address)) {
builder.addPropertyValue("emailAddress", address);
}
}
}
```
- 创建 resource/META-INF/spring.handlers
```text
http\://www.huifer.com/schema/user=com.huifer.source.spring.parser.UserNamespaceHandler
```
- 创建 resource/META-INF/spring.schemas
```text
http\://www.huifer.com/schema/user.xsd=META-INF/spring-test.xsd
```
- 创建测试用例xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:myname="http://www.huifer.com/schema/user"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.huifer.com/schema/user http://www.huifer.com/schema/user.xsd
">
<myname:myUser id="testUserBean" userName="huifer" emailAddress="huifer97@163.com"/>
</beans>
```
- 创建 Java 运行方法
```java
/**
* 自定义标签测试用例
*/
public class XSDDemo {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("XTD-xml.xml");
UserXtd user = (UserXtd) applicationContext.getBean("testUserBean");
System.out.println(user.getEmailAddress());
}
}
```
- 这里我们希望输出结果是`huifer97@163.com`,运行后结果也确实是`huifer97@163.com`
## 解析 DefaultNamespaceHandlerResolver
- 入口方法`org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions`
```java
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
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)) {
// 不同标签的解析
parseDefaultElement(ele, delegate);
}
else {
// 非spring 默认标签解析
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
```
- 调用链路
- `org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(org.w3c.dom.Element)`
- `org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)`
```java
/**
* Parse a custom element (outside of the default namespace).
* <p>
* 自定义标签解析
*
* @param ele the element to parse
* @param containingBd the containing bean definition (if any)
* @return the resulting bean definition
*/
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
// 自定义标签解析
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 根据命名空间获取处理类
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 自定义处理器
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
```
![image-20200109084131415](/images/spring/image-20200109084131415.png)
- `http://www.huifer.com/schema/user`和我们定义的xsd文件中的url相同如何找到对应的NamespaceHandler,在`META-INF/spring.handlers`中有定义,
`http\://www.huifer.com/schema/user=com.huifer.source.spring.parser.UserNamespaceHandler`
`NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);`这行代码就是获取`spring.handlers`中的定义
- 处理方法`org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve`
```java
/**
* Locate the {@link NamespaceHandler} for the supplied namespace URI
* from the configured mappings.
*
* 根据 namespaceUri 获取对应的 {@link NamespaceHandler}
* @param namespaceUri the relevant namespace URI
* @return the located {@link NamespaceHandler}, or {@code null} if none found
*/
@Override
@Nullable
public NamespaceHandler resolve(String namespaceUri) {
// 获取handlerMapping
Map<String, Object> handlerMappings = getHandlerMappings();
// 从 handlerMapping 中获取类名
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
// 判断是否处理过,处理过直接返回
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
else {
// 没有处理,进行反射还原类
String className = (String) handlerOrClassName;
try {
// 通过反射还原类
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
// 初始化类
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
// 调用init()方法,自定义类中实现
namespaceHandler.init();
// 放入缓存
handlerMappings.put(namespaceUri, namespaceHandler);
// 返回自定义的 namespaceHandler
return namespaceHandler;
}
catch (ClassNotFoundException ex) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
"] for namespace [" + namespaceUri + "]", ex);
}
catch (LinkageError err) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
```
- `org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#getHandlerMappings`跟踪这个方法
```JAVA
/**
* Load the specified NamespaceHandler mappings lazily.
*
* 获取handlerMappings
*/
private Map<String, Object> getHandlerMappings() {
Map<String, Object> handlerMappings = this.handlerMappings;
}
```
![image-20200109085606240](/images/spring/image-20200109085606240.png)
- 这里直接存在数据了,他是从什么时候加载的?
- `org.springframework.beans.factory.xml.XmlBeanDefinitionReader#registerBeanDefinitions`
这个方法在注册bean定义的时候调用
```java
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
// 注册方法
// createReaderContext 初始化HandlerMapping
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
```
- 继续跟踪`createReaderContext`
```java
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#createReaderContext
```
```java
public XmlReaderContext createReaderContext(Resource resource) {
return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
this.sourceExtractor, this, getNamespaceHandlerResolver());
}
```
- 继续跟踪`getNamespaceHandlerResolver`
`org.springframework.beans.factory.xml.XmlBeanDefinitionReader#getNamespaceHandlerResolver`
```java
public NamespaceHandlerResolver getNamespaceHandlerResolver() {
if (this.namespaceHandlerResolver == null) {
this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
}
return this.namespaceHandlerResolver;
}
```
- 继续跟踪`createDefaultNamespaceHandlerResolver`
`org.springframework.beans.factory.xml.XmlBeanDefinitionReader#createDefaultNamespaceHandlerResolver`
```java
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader());
return new DefaultNamespaceHandlerResolver(cl);
}
```
- 继续跟踪`DefaultNamespaceHandlerResolver`
`org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver`
```java
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader) {
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
```
他回到了我们之前疑问的地方 `handlerMappings` 如何出现的
断点
![image-20200109090456547](/images/spring/image-20200109090456547.png)
```JAVA
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader) {
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
```
`public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";`
![image-20200109090655157](/images/spring/image-20200109090655157.png)
此时还是空
走完
![image-20200109091216505](/images/spring/image-20200109091216505.png)
```java
@Override
public String toString() {
return "NamespaceHandlerResolver using mappings " + getHandlerMappings();
}
```
```JAVA
/**
* Load the specified NamespaceHandler mappings lazily.
*
* 获取handlerMappings
*/
private Map<String, Object> getHandlerMappings() {
Map<String, Object> handlerMappings = this.handlerMappings;
// 缓存不存在
if (handlerMappings == null) {
synchronized (this) {
handlerMappings = this.handlerMappings;
if (handlerMappings == null) {
if (logger.isTraceEnabled()) {
logger.trace("Loading NamespaceHandler mappings from [" + this.handlerMappingsLocation + "]");
}
try {
// 将本地文件读出
Properties mappings =
PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
if (logger.isTraceEnabled()) {
logger.trace("Loaded NamespaceHandler mappings: " + mappings);
}
handlerMappings = new ConcurrentHashMap<>(mappings.size());
// 转换成map结构
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
this.handlerMappings = handlerMappings;
}
catch (IOException ex) {
throw new IllegalStateException(
"Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex);
}
}
}
}
return handlerMappings;
}
```
![image-20200109094032421](/images/spring/image-20200109094032421.png)
## org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve
```java
@Override
@Nullable
public NamespaceHandler resolve(String namespaceUri) {
// 获取handlerMapping
Map<String, Object> handlerMappings = getHandlerMappings();
// 从 handlerMapping 中获取类名
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
// 判断是否处理过,处理过直接返回
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
else {
// 没有处理,进行反射还原类
String className = (String) handlerOrClassName;
try {
// 通过反射还原类
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
// 初始化类
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
// 调用init()方法,自定义类中实现
namespaceHandler.init();
// 放入缓存
handlerMappings.put(namespaceUri, namespaceHandler);
// 返回自定义的 namespaceHandler
return namespaceHandler;
}
catch (ClassNotFoundException ex) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
"] for namespace [" + namespaceUri + "]", ex);
}
catch (LinkageError err) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
```
执行`init`方法
```java
public class UserNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("myUser", new UserBeanDefinitionParser());
}
}
```
```java
/**
* Subclasses can call this to register the supplied {@link BeanDefinitionParser} to
* handle the specified element. The element name is the local (non-namespace qualified)
* name.
*
* 将标签名称,标签解析类放入
*/
protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
this.parsers.put(elementName, parser);
}
```
- 方法走完,回到开始的方法
```java
/**
* Parse a custom element (outside of the default namespace).
* <p>
* 自定义标签解析
*
* @param ele the element to parse
* @param containingBd the containing bean definition (if any)
* @return the resulting bean definition
*/
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
// 自定义标签解析
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 根据命名空间获取处理类
// org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 自定义处理器
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
```
![image-20200109092801572](/images/spring/image-20200109092801572.png)
## org.springframework.beans.factory.xml.NamespaceHandler#parse
- `org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse`
```java
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinitionParser parser = findParserForElement(element, parserContext);
return (parser != null ? parser.parse(element, parserContext) : null);
}
```
### org.springframework.beans.factory.xml.NamespaceHandlerSupport#findParserForElement
```java
@Nullable
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
// 获取标签名称
String localName = parserContext.getDelegate().getLocalName(element);
// 在map中获取对应的标签解析类
BeanDefinitionParser parser = this.parsers.get(localName);
// 空报错
if (parser == null) {
parserContext.getReaderContext().fatal(
"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
}
// 不为空返回
return parser;
}
```
![image-20200109093242494](/images/spring/image-20200109093242494.png)
### org.springframework.beans.factory.xml.BeanDefinitionParser#parse
- `org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parse`
```java
public final BeanDefinition parse(Element element, ParserContext parserContext) {
/**
* {@link AbstractSingleBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)}
*/
AbstractBeanDefinition definition = parseInternal(element, parserContext);
}
```
### org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#parseInternal
```java
@Override
protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
String parentName = getParentName(element);
if (parentName != null) {
builder.getRawBeanDefinition().setParentName(parentName);
}
// 调用自己实现的方法 com.huifer.source.spring.parser.UserBeanDefinitionParser.getBeanClass
Class<?> beanClass = getBeanClass(element);
if (beanClass != null) {
builder.getRawBeanDefinition().setBeanClass(beanClass);
}
else {
// getBeanClassName 同样也是可以在自定义的解析类中实现
String beanClassName = getBeanClassName(element);
if (beanClassName != null) {
builder.getRawBeanDefinition().setBeanClassName(beanClassName);
}
}
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
BeanDefinition containingBd = parserContext.getContainingBeanDefinition();
if (containingBd != null) {
// Inner bean definition must receive same scope as containing bean.
// 设置scope
builder.setScope(containingBd.getScope());
}
if (parserContext.isDefaultLazyInit()) {
// Default-lazy-init applies to custom bean definitions as well.
// 设置 lazy-init
builder.setLazyInit(true);
}
// 执行解析方法,在自定义解析类中存在com.huifer.source.spring.parser.UserBeanDefinitionParser.doParse
doParse(element, parserContext, builder);
return builder.getBeanDefinition();
}
```
![image-20200109094654409](/images/spring/image-20200109094654409.png)
执行`com.huifer.source.spring.parser.UserBeanDefinitionParser#doParse`
```JAVA
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
// 获取 userName 标签属性值
String name = element.getAttribute("userName");
// 获取 emailAddress 标签属性值
String address = element.getAttribute("emailAddress");
if (StringUtils.hasText(name)) {
builder.addPropertyValue("userName", name);
}
if (StringUtils.hasText(address)) {
builder.addPropertyValue("emailAddress", address);
}
}
```

@ -0,0 +1,522 @@
# Spring JDBC
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
## 环境搭建
- 依赖
```gradle
compile(project(":spring-jdbc"))
compile group: 'com.alibaba', name: 'druid', version: '1.1.21'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.47'
```
- db配置
```properties
jdbc.url=
jdbc.driverClass=
jdbc.username=
jdbc.password=
```
- 实体对象
```JAVA
public class HsLog {
private Integer id;
private String source;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
}
```
- DAO
```JAVA
public interface HsLogDao {
List<HsLog> findAll();
void save(HsLog hsLog);
}
```
- 实现类
```JAVA
public class HsLogDaoImpl extends JdbcDaoSupport implements HsLogDao {
@Override
public List<HsLog> findAll() {
return this.getJdbcTemplate().query("select * from hs_log", new HsLogRowMapper());
}
@Override
public void save(HsLog hsLog) {
this.getJdbcTemplate().update("insert into hs_log (SOURCE) values(?)"
, new Object[]{
hsLog.getSource(),
}
);
}
class HsLogRowMapper implements RowMapper<HsLog> {
public HsLog mapRow(ResultSet rs, int rowNum) throws SQLException {
HsLog log = new HsLog();
log.setId(rs.getInt("id"));
log.setSource(rs.getString("source"));
return log;
}
}
}
```
- xml
```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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"
>
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url"
value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="maxActive" value="20"/>
<property name="initialSize" value="1"/>
<property name="minIdle" value="1"/>
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
<!-- 打开PSCache并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true"/>
<property name="maxOpenPreparedStatements" value="20"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="hsLogDao" class="com.huifer.source.spring.dao.impl.HsLogDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
</beans>
```
- 运行方法
```JAVA
public class SpringJDBCSourceCode {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("JDBC-demo.xml");
HsLogDaoImpl bean = applicationContext.getBean(HsLogDaoImpl.class);
System.out.println(bean.findAll());
HsLog hsLog = new HsLog();
hsLog.setSource("jlkjll");
bean.save(hsLog);
}
}
```
## 链接对象构造
`Connection con = DataSourceUtils.getConnection(obtainDataSource());`
```java
public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException {
try {
return doGetConnection(dataSource);
}
catch (SQLException ex) {
throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection", ex);
}
catch (IllegalStateException ex) {
throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection: " + ex.getMessage());
}
}
```
### org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection
```java
public static Connection doGetConnection(DataSource dataSource) throws SQLException {
Assert.notNull(dataSource, "No DataSource specified");
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
conHolder.requested();
if (!conHolder.hasConnection()) {
logger.debug("Fetching resumed JDBC Connection from DataSource");
// 设置连接对象
conHolder.setConnection(fetchConnection(dataSource));
}
return conHolder.getConnection();
}
// Else we either got no holder or an empty thread-bound holder here.
logger.debug("Fetching JDBC Connection from DataSource");
// 获取链接
Connection con = fetchConnection(dataSource);
// 当前线程支持同步
if (TransactionSynchronizationManager.isSynchronizationActive()) {
try {
// Use same Connection for further JDBC actions within the transaction.
// Thread-bound object will get removed by synchronization at transaction completion.
// 在同一个事物中使用同一个链接对象
ConnectionHolder holderToUse = conHolder;
if (holderToUse == null) {
holderToUse = new ConnectionHolder(con);
}
else {
holderToUse.setConnection(con);
}
// 记录链接数量
holderToUse.requested();
TransactionSynchronizationManager.registerSynchronization(
new ConnectionSynchronization(holderToUse, dataSource));
holderToUse.setSynchronizedWithTransaction(true);
if (holderToUse != conHolder) {
TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
}
}
catch (RuntimeException ex) {
// Unexpected exception from external delegation call -> close Connection and rethrow.
releaseConnection(con, dataSource);
throw ex;
}
}
return con;
}
```
## 释放资源
`releaseConnection(con, dataSource);`
- `org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection`
```JAVA
public static void releaseConnection(@Nullable Connection con, @Nullable DataSource dataSource) {
try {
doReleaseConnection(con, dataSource);
}
catch (SQLException ex) {
logger.debug("Could not close JDBC Connection", ex);
}
catch (Throwable ex) {
logger.debug("Unexpected exception on closing JDBC Connection", ex);
}
}
```
```java
public static void doReleaseConnection(@Nullable Connection con, @Nullable DataSource dataSource) throws SQLException {
if (con == null) {
return;
}
if (dataSource != null) {
ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
if (conHolder != null && connectionEquals(conHolder, con)) {
// It's the transactional Connection: Don't close it.
// 连接数-1
conHolder.released();
return;
}
}
// 处理其他情况
doCloseConnection(con, dataSource);
}
```
### org.springframework.transaction.support.ResourceHolderSupport
链接数
```JAVA
/**
* Increase the reference count by one because the holder has been requested
* (i.e. someone requested the resource held by it).
*/
public void requested() {
this.referenceCount++;
}
/**
* Decrease the reference count by one because the holder has been released
* (i.e. someone released the resource held by it).
*/
public void released() {
this.referenceCount--;
}
```
## 查询解析
### org.springframework.jdbc.core.JdbcTemplate
```XML
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
```
- 从配置中可以知道 JdbcTemplate 需要 dataSource 属性, 就从这里开始讲起
- `org.springframework.jdbc.support.JdbcAccessor.setDataSource`, 这段代码就只做了赋值操作(依赖注入)
```java
public void setDataSource(@Nullable DataSource dataSource) {
this.dataSource = dataSource;
}
```
- 下面`hsLogDao`也是依赖注入本篇不做详细讲述。
### org.springframework.jdbc.core.JdbcTemplate#query(java.lang.String, org.springframework.jdbc.core.RowMapper<T>)
```java
@Override
public List<HsLog> findAll() {
return this.getJdbcTemplate().query("select * from hs_log", new HsLogRowMapper());
}
```
```java
@Override
@Nullable
public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
Assert.notNull(rse, "ResultSetExtractor must not be null");
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL query [" + sql + "]");
}
/**
* Callback to execute the query.
*/
class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
@Override
@Nullable
public T doInStatement(Statement stmt) throws SQLException {
ResultSet rs = null;
try {
// 执行sql
rs = stmt.executeQuery(sql);
// 1. org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData
return rse.extractData(rs);
}
finally {
JdbcUtils.closeResultSet(rs);
}
}
@Override
public String getSql() {
return sql;
}
}
return execute(new QueryStatementCallback());
}
```
```java
@Override
@Nullable
public <T> T execute(StatementCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Connection con = DataSourceUtils.getConnection(obtainDataSource());
Statement stmt = null;
try {
stmt = con.createStatement();
applyStatementSettings(stmt);
// 执行
T result = action.doInStatement(stmt);
handleWarnings(stmt);
return result;
}
catch (SQLException ex) {
// Release Connection early, to avoid potential connection pool deadlock
// in the case when the exception translator hasn't been initialized yet.
String sql = getSql(action);
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw translateException("StatementCallback", sql, ex);
}
finally {
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
```
```JAVA
@Override
public List<T> extractData(ResultSet rs) throws SQLException {
List<T> results = (this.rowsExpected > 0 ? new ArrayList<>(this.rowsExpected) : new ArrayList<>());
int rowNum = 0;
while (rs.next()) {
// 调用自定义的 rowMapper 进行数据处理
T t = this.rowMapper.mapRow(rs, rowNum++);
results.add(t);
}
return results;
}
```
![image-20200109150841916](/images/spring/image-20200109150841916.png)
这样就可以获取到了
方法`result`没有什么操作直接返回即可
```java
private static <T> T result(@Nullable T result) {
Assert.state(result != null, "No result");
return result;
}
```
## 插入解析
```java
@Override
public void save(HsLog hsLog) {
this.getJdbcTemplate().update("insert into hs_log (SOURCE) values(?)"
, new Object[]{
hsLog.getSource(),
}
);
}
```
`org.springframework.jdbc.core.JdbcTemplate#update(org.springframework.jdbc.core.PreparedStatementCreator, org.springframework.jdbc.core.PreparedStatementSetter)`
```java
protected int update(final PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss)
throws DataAccessException {
logger.debug("Executing prepared SQL update");
return updateCount(execute(psc, ps -> {
try {
if (pss != null) {
// 设置请求参数
pss.setValues(ps);
}
int rows = ps.executeUpdate();
if (logger.isTraceEnabled()) {
logger.trace("SQL update affected " + rows + " rows");
}
return rows;
}
finally {
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
}
}
}));
}
```

@ -0,0 +1,124 @@
# Spring5 新特性 - spring.components
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
## 解析
- 相关类: `org.springframework.context.index.CandidateComponentsIndexLoader`
- 测试用例: `org.springframework.context.annotation.ClassPathScanningCandidateComponentProviderTests.defaultsWithIndex`,`org.springframework.context.index.CandidateComponentsIndexLoaderTests`
- `CandidateComponentsIndexLoader`是怎么找出来的,全文搜索`spring.components`
### 使用介绍
- 下面是从`resources/example/scannable/spring.components`测试用例中复制过来的,从中可以发现等号左侧放的是我们写的组件,等号右边是属于什么组件
```
example.scannable.AutowiredQualifierFooService=example.scannable.FooService
example.scannable.DefaultNamedComponent=org.springframework.stereotype.Component
example.scannable.NamedComponent=org.springframework.stereotype.Component
example.scannable.FooService=example.scannable.FooService
example.scannable.FooServiceImpl=org.springframework.stereotype.Component,example.scannable.FooService
example.scannable.ScopedProxyTestBean=example.scannable.FooService
example.scannable.StubFooDao=org.springframework.stereotype.Component
example.scannable.NamedStubDao=org.springframework.stereotype.Component
example.scannable.ServiceInvocationCounter=org.springframework.stereotype.Component
example.scannable.sub.BarComponent=org.springframework.stereotype.Component
```
### debug
- 入口 `org.springframework.context.index.CandidateComponentsIndexLoader.loadIndex`
```java
@Nullable
public static CandidateComponentsIndex loadIndex(@Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = CandidateComponentsIndexLoader.class.getClassLoader();
}
return cache.computeIfAbsent(classLoaderToUse, CandidateComponentsIndexLoader::doLoadIndex);
}
```
```java
/**
* 解析 META-INF/spring.components 文件
* @param classLoader
* @return
*/
@Nullable
private static CandidateComponentsIndex doLoadIndex(ClassLoader classLoader) {
if (shouldIgnoreIndex) {
return null;
}
try {
Enumeration<URL> urls = classLoader.getResources(COMPONENTS_RESOURCE_LOCATION);
if (!urls.hasMoreElements()) {
return null;
}
List<Properties> result = new ArrayList<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
// 读取META-INF/spring.components文件转换成map对象
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
result.add(properties);
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + result.size() + "] index(es)");
}
int totalCount = result.stream().mapToInt(Properties::size).sum();
// 查看CandidateComponentsIndex方法
return (totalCount > 0 ? new CandidateComponentsIndex(result) : null);
}
catch (IOException ex) {
throw new IllegalStateException("Unable to load indexes from location [" +
COMPONENTS_RESOURCE_LOCATION + "]", ex);
}
}
```
```java
CandidateComponentsIndex(List<Properties> content) {
this.index = parseIndex(content);
}
/**
* 解析 MATE-INF\spring.components 转换成 map
*
* @param content
* @return
*/
private static MultiValueMap<String, Entry> parseIndex(List<Properties> content) {
MultiValueMap<String, Entry> index = new LinkedMultiValueMap<>();
for (Properties entry : content) {
entry.forEach((type, values) -> {
String[] stereotypes = ((String) values).split(",");
for (String stereotype : stereotypes) {
index.add(stereotype, new Entry((String) type));
}
});
}
return index;
}
```
![image-20200115105941265](/images/spring/image-20200115105941265.png)
- 该类给`org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents`提供了帮助
```java
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
// 扫描
/**
* if 测试用例: {@link org.springframework.context.annotation.ClassPathScanningCandidateComponentProviderTests#defaultsWithIndex()}
* 解析 spring.components文件
*/
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
return scanCandidateComponents(basePackage);
}
}
```

@ -0,0 +1,518 @@
# Spring AnnotationUtils
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
- `org.springframework.core.annotation.AnnotationUtils`提供了注解相关的方法
1. getAnnotation: 获取注解
1. findAnnotation: 寻找注解
1. getValue: 获取属性值
1. getDefaultValue: 获取默认值
## getAnnotation
- 测试用例如下
```java
@Test
public void findMethodAnnotationOnLeaf() throws Exception {
Method m = Leaf.class.getMethod("annotatedOnLeaf");
assertNotNull(m.getAnnotation(Order.class));
assertNotNull(getAnnotation(m, Order.class));
assertNotNull(findAnnotation(m, Order.class));
}
```
- `org.springframework.core.annotation.AnnotationUtils.getAnnotation(java.lang.reflect.Method, java.lang.Class<A>)`
```java
/**
* Get a single {@link Annotation} of {@code annotationType} from the
* supplied {@link Method}, where the annotation is either <em>present</em>
* or <em>meta-present</em> on the method.
* <p>Correctly handles bridge {@link Method Methods} generated by the compiler.
* <p>Note that this method supports only a single level of meta-annotations.
* For support for arbitrary levels of meta-annotations, use
* {@link #findAnnotation(Method, Class)} instead.
*
* @param method the method to look for annotations on
* 被检查的函数
* @param annotationType the annotation type to look for
* 需要检测的注解类型
* @return the first matching annotation, or {@code null} if not found
* @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method)
* @see #getAnnotation(AnnotatedElement, Class)
*/
@Nullable
public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) {
// 函数
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
// 强制转换
return getAnnotation((AnnotatedElement) resolvedMethod, annotationType);
}
```
- method
![image-20200116085344737](/images/spring/image-20200116085344737.png)
- annotationType
![image-20200116085423073](/images/spring/image-20200116085423073.png)
```java
@Nullable
public static <A extends Annotation> A getAnnotation(AnnotatedElement annotatedElement, Class<A> annotationType) {
try {
// 获取注解
A annotation = annotatedElement.getAnnotation(annotationType);
if (annotation == null) {
for (Annotation metaAnn : annotatedElement.getAnnotations()) {
annotation = metaAnn.annotationType().getAnnotation(annotationType);
if (annotation != null) {
break;
}
}
}
return (annotation != null ? synthesizeAnnotation(annotation, annotatedElement) : null);
} catch (Throwable ex) {
handleIntrospectionFailure(annotatedElement, ex);
return null;
}
}
```
- `org.springframework.core.annotation.AnnotationUtils.synthesizeAnnotation(A, java.lang.reflect.AnnotatedElement)`
```java
public static <A extends Annotation> A synthesizeAnnotation(
A annotation, @Nullable AnnotatedElement annotatedElement) {
return synthesizeAnnotation(annotation, (Object) annotatedElement);
}
```
```java
/**
* 注解是否存在别名,没有直接返回
*
* @param annotation 注解
* @param annotatedElement 函数
* @param <A>
* @return
*/
@SuppressWarnings("unchecked")
static <A extends Annotation> A synthesizeAnnotation(A annotation, @Nullable Object annotatedElement) {
if (annotation instanceof SynthesizedAnnotation || hasPlainJavaAnnotationsOnly(annotatedElement)) {
return annotation;
}
// 具体的注解
Class<? extends Annotation> annotationType = annotation.annotationType();
if (!isSynthesizable(annotationType)) {
return annotation;
}
DefaultAnnotationAttributeExtractor attributeExtractor =
new DefaultAnnotationAttributeExtractor(annotation, annotatedElement);
InvocationHandler handler = new SynthesizedAnnotationInvocationHandler(attributeExtractor);
// Can always expose Spring's SynthesizedAnnotation marker since we explicitly check for a
// synthesizable annotation before (which needs to declare @AliasFor from the same package)
Class<?>[] exposedInterfaces = new Class<?>[]{annotationType, SynthesizedAnnotation.class};
return (A) Proxy.newProxyInstance(annotation.getClass().getClassLoader(), exposedInterfaces, handler);
}
```
-`org.springframework.core.annotation.AnnotationUtils.isSynthesizable`
```java
@SuppressWarnings("unchecked")
private static boolean isSynthesizable(Class<? extends Annotation> annotationType) {
if (hasPlainJavaAnnotationsOnly(annotationType)) {
return false;
}
// 从缓存中获取当前注解,不存在null
Boolean synthesizable = synthesizableCache.get(annotationType);
if (synthesizable != null) {
return synthesizable;
}
synthesizable = Boolean.FALSE;
for (Method attribute : getAttributeMethods(annotationType)) {
if (!getAttributeAliasNames(attribute).isEmpty()) {
synthesizable = Boolean.TRUE;
break;
}
// 获取返回值类型
Class<?> returnType = attribute.getReturnType();
// 根据返回值做不同处理
if (Annotation[].class.isAssignableFrom(returnType)) {
Class<? extends Annotation> nestedAnnotationType =
(Class<? extends Annotation>) returnType.getComponentType();
if (isSynthesizable(nestedAnnotationType)) {
synthesizable = Boolean.TRUE;
break;
}
} else if (Annotation.class.isAssignableFrom(returnType)) {
Class<? extends Annotation> nestedAnnotationType = (Class<? extends Annotation>) returnType;
if (isSynthesizable(nestedAnnotationType)) {
synthesizable = Boolean.TRUE;
break;
}
}
}
synthesizableCache.put(annotationType, synthesizable);
return synthesizable;
}
```
- `org.springframework.core.annotation.AnnotationUtils#getAttributeMethods`
```java
static List<Method> getAttributeMethods(Class<? extends Annotation> annotationType) {
List<Method> methods = attributeMethodsCache.get(annotationType);
if (methods != null) {
return methods;
}
methods = new ArrayList<>();
// annotationType.getDeclaredMethods() 获取注解中的方法
for (Method method : annotationType.getDeclaredMethods()) {
if (isAttributeMethod(method)) {
ReflectionUtils.makeAccessible(method);
methods.add(method);
}
}
// 缓存 key:注解,value:函数列表
attributeMethodsCache.put(annotationType, methods);
// 函数列表
return methods;
}
```
- `org.springframework.core.annotation.AnnotationUtils#isAttributeMethod`
```java
/**
* Determine if the supplied {@code method} is an annotation attribute method.
* <p>
* 做3个判断
* <ol>
* <li>函数不为空(method != null)</li>
* <li>参数列表是不是空(method.getParameterCount() == 0)</li>
* <li>返回类型不是void(method.getReturnType() != void.class)</li>
* </ol>
*
* @param method the method to check
* @return {@code true} if the method is an attribute method
* @since 4.2
*/
static boolean isAttributeMethod(@Nullable Method method) {
return (method != null && method.getParameterCount() == 0 && method.getReturnType() != void.class);
}
```
- `org.springframework.util.ReflectionUtils#makeAccessible(java.lang.reflect.Method)`
```java
@SuppressWarnings("deprecation") // on JDK 9
public static void makeAccessible(Method method) {
// 1. 方法修饰符是不是public
// 2. 注解是不是public
// 3. 是否重写
if ((!Modifier.isPublic(method.getModifiers()) ||
!Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) {
method.setAccessible(true);
}
}
```
处理结果
![image-20200116085726577](/images/spring/image-20200116085726577.png)
![image-20200116085737632](/images/spring/image-20200116085737632.png)
处理结果和Order定义相同
```java
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {
/**
* The order value.
* <p>Default is {@link Ordered#LOWEST_PRECEDENCE}.
*
* 启动顺序,默认integer最大值
* @see Ordered#getOrder()
*/
int value() default Ordered.LOWEST_PRECEDENCE;
}
```
最终返回
![image-20200116085927359](/images/spring/image-20200116085927359.png)
## findAnnotation
- `org.springframework.core.annotation.AnnotationUtils#findAnnotation(java.lang.reflect.Method, java.lang.Class<A>)`
```java
@SuppressWarnings("unchecked")
@Nullable
public static <A extends Annotation> A findAnnotation(Method method, @Nullable Class<A> annotationType) {
Assert.notNull(method, "Method must not be null");
if (annotationType == null) {
return null;
}
// 创建注解缓存,key:被扫描的函数,value:注解
AnnotationCacheKey cacheKey = new AnnotationCacheKey(method, annotationType);
// 从findAnnotationCache获取缓存
A result = (A) findAnnotationCache.get(cacheKey);
if (result == null) {
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
// 寻找注解
result = findAnnotation((AnnotatedElement) resolvedMethod, annotationType);
if (result == null) {
result = searchOnInterfaces(method, annotationType, method.getDeclaringClass().getInterfaces());
}
Class<?> clazz = method.getDeclaringClass();
while (result == null) {
clazz = clazz.getSuperclass();
if (clazz == null || clazz == Object.class) {
break;
}
Set<Method> annotatedMethods = getAnnotatedMethodsInBaseType(clazz);
if (!annotatedMethods.isEmpty()) {
for (Method annotatedMethod : annotatedMethods) {
if (isOverride(method, annotatedMethod)) {
Method resolvedSuperMethod = BridgeMethodResolver.findBridgedMethod(annotatedMethod);
result = findAnnotation((AnnotatedElement) resolvedSuperMethod, annotationType);
if (result != null) {
break;
}
}
}
}
if (result == null) {
result = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
}
}
if (result != null) {
// 处理注解
result = synthesizeAnnotation(result, method);
// 添加缓存
findAnnotationCache.put(cacheKey, result);
}
}
// 返回
return result;
}
```
- `org.springframework.core.annotation.AnnotationUtils.AnnotationCacheKey`
```java
private static final class AnnotationCacheKey implements Comparable<AnnotationCacheKey> {
/**
* 带有注解的函数或者类
*/
private final AnnotatedElement element;
/**
* 注解
*/
private final Class<? extends Annotation> annotationType;
public AnnotationCacheKey(AnnotatedElement element, Class<? extends Annotation> annotationType) {
this.element = element;
this.annotationType = annotationType;
}
}
```
- `org.springframework.core.annotation.AnnotationUtils#findAnnotation(java.lang.reflect.AnnotatedElement, java.lang.Class<A>)`
```java
@Nullable
public static <A extends Annotation> A findAnnotation(
AnnotatedElement annotatedElement, @Nullable Class<A> annotationType) {
// 注解类型不为空
if (annotationType == null) {
return null;
}
// Do NOT store result in the findAnnotationCache since doing so could break
// findAnnotation(Class, Class) and findAnnotation(Method, Class).
// 寻找注解
A ann = findAnnotation(annotatedElement, annotationType, new HashSet<>());
return (ann != null ? synthesizeAnnotation(ann, annotatedElement) : null);
}
```
- `org.springframework.core.annotation.AnnotationUtils#findAnnotation(java.lang.reflect.AnnotatedElement, java.lang.Class<A>, java.util.Set<java.lang.annotation.Annotation>)`
```java
@Nullable
private static <A extends Annotation> A findAnnotation(
AnnotatedElement annotatedElement, Class<A> annotationType, Set<Annotation> visited) {
try {
// 直接获取注解
A annotation = annotatedElement.getDeclaredAnnotation(annotationType);
if (annotation != null) {
return annotation;
}
// 多级注解
for (Annotation declaredAnn : getDeclaredAnnotations(annotatedElement)) {
Class<? extends Annotation> declaredType = declaredAnn.annotationType();
// 注解是否 由java.lang.annotation提供
if (!isInJavaLangAnnotationPackage(declaredType) && visited.add(declaredAnn)) {
annotation = findAnnotation((AnnotatedElement) declaredType, annotationType, visited);
if (annotation != null) {
return annotation;
}
}
}
} catch (Throwable ex) {
handleIntrospectionFailure(annotatedElement, ex);
}
return null;
}
```
![image-20200116092259944](/images/spring/image-20200116092259944.png)
- `synthesizeAnnotation`方法就不再重复一遍了可以看上文
## getValue
- 测试用例
```java
@Test
public void getValueFromAnnotation() throws Exception {
Method method = SimpleFoo.class.getMethod("something", Object.class);
Order order = findAnnotation(method, Order.class);
assertEquals(1, getValue(order, VALUE));
assertEquals(1, getValue(order));
}
```
- `org.springframework.core.annotation.AnnotationUtils#getValue(java.lang.annotation.Annotation, java.lang.String)`
```java
@Nullable
public static Object getValue(@Nullable Annotation annotation, @Nullable String attributeName) {
if (annotation == null || !StringUtils.hasText(attributeName)) {
return null;
}
try {
// 根据attributeName获取注解对应函数
Method method = annotation.annotationType().getDeclaredMethod(attributeName);
ReflectionUtils.makeAccessible(method);
// 反射执行方法
return method.invoke(annotation);
} catch (NoSuchMethodException ex) {
return null;
} catch (InvocationTargetException ex) {
rethrowAnnotationConfigurationException(ex.getTargetException());
throw new IllegalStateException("Could not obtain value for annotation attribute '" +
attributeName + "' in " + annotation, ex);
} catch (Throwable ex) {
handleIntrospectionFailure(annotation.getClass(), ex);
return null;
}
}
```
```java
@Nullable
public static Object getValue(Annotation annotation) {
return getValue(annotation, VALUE);
}
```
## getDefaultValue
- `org.springframework.core.annotation.AnnotationUtils#getDefaultValue(java.lang.annotation.Annotation)`
```java
@Nullable
public static Object getDefaultValue(Annotation annotation) {
return getDefaultValue(annotation, VALUE);
}
```
```java
@Nullable
public static Object getDefaultValue(
@Nullable Class<? extends Annotation> annotationType, @Nullable String attributeName) {
if (annotationType == null || !StringUtils.hasText(attributeName)) {
return null;
}
try {
// 直接获取defaultValue
return annotationType.getDeclaredMethod(attributeName).getDefaultValue();
} catch (Throwable ex) {
handleIntrospectionFailure(annotationType, ex);
return null;
}
}
```

@ -0,0 +1,447 @@
# Spring BeanFactoryPostProcessor
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
- 作用: 定制或修改`BeanDefinition`的属性
## Demo
```java
public class ChangeAttrBeanPostProcessor implements BeanFactoryPostProcessor {
private Set<String> attr;
public ChangeAttrBeanPostProcessor() {
attr = new HashSet<>();
}
public Set<String> getAttr() {
return attr;
}
public void setAttr(Set<String> attr) {
this.attr = attr;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanDefinitionNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
StringValueResolver stringValueResolver = new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
if (attr.contains(strVal)) {
return "隐藏属性";
}
else {
return strVal;
}
}
};
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(stringValueResolver);
visitor.visitBeanDefinition(beanDefinition);
}
}
}
```
```java
public class BeanFactoryPostProcessorSourceCode {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("BeanFactoryPostProcessor-demo.xml");
Apple apple = context.getBean("apple", Apple.class);
System.out.println(apple);
}
}
```
```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">
<bean id="removeAttrBeanPostProcessor"
class="com.huifer.source.spring.beanPostProcessor.ChangeAttrBeanPostProcessor">
<property name="attr">
<set>
<value>hc</value>
</set>
</property>
</bean>
<bean id="apple" class="com.huifer.source.spring.bean.Apple">
<property name="name" value="hc"/>
</bean>
</beans>
```
## 初始化
- `org.springframework.context.support.AbstractApplicationContext#refresh`
```JAVA
invokeBeanFactoryPostProcessors(beanFactory);
```
```JAVA
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
```
- `org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)`
```JAVA
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 判断是否为BeanDefinitionRegistry类
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 存放 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 存放 BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 2.首先处理入参中的beanFactoryPostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 判断是否是BeanDefinitionRegistryPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// BeanDefinitionRegistryPostProcessor 添加
// 执行 postProcessBeanFactory
registryProcessors.add(registryProcessor);
}
// 这部分else 内容就是 BeanFactoryPostProcessor
else {
// BeanFactoryPostProcessor 添加
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
/**
* 调用实现{@link PriorityOrdered}\{@link BeanDefinitionRegistryPostProcessor}
* todo: 2020年1月16日 解析方法
* {@link DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class, boolean, boolean)}
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序Order
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 配置文件中的 BeanFactoryPostProcessor 处理
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
// 处理过的跳过
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 配置文件中自定义的 BeanFactoryPostProcessor 注册
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
```
![image-20200119085346675](/images/spring/image-20200119085346675.png)
![image-20200119085655734](/images/spring/image-20200119085655734.png)
## InstantiationAwareBeanPostProcessor
```java
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
```
```java
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取 BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// 获取数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// BeanPostProcessor 通过PriorityOrdered保证顺序
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// MergedBeanDefinitionPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 有序的 BeanPostProcessor
List<String> orderedPostProcessorNames = new ArrayList<>();
// 无序的 BeanPostProcessor
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// 类型判断放入相应的list
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
/**
* 有{@link org.springframework.core.annotation.Order} 相关操作
*/
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 注册 BeanPostProcessor 和 PriorityOrdered 实现
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
// 注册 实现Order 和 BeanPostProcessor
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 注册无序的 BeanPostProcessor
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
// 注册 MergedBeanDefinitionPostProcessor
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 添加 ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
```
- 测试用Bean
```java
public class DemoInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("init bean beanClass = " + beanClass.getSimpleName() + " beanName = " + beanName);
return null;
}
}
```
- 按照笔者的注释,可以知道`DemoInstantiationAwareBeanPostProcessor` 这个类是一个无序Bean
![image-20200119101026726](/images/spring/image-20200119101026726.png)
![image-20200119101017989](/images/spring/image-20200119101017989.png)
- 注册方法信息截图
![image-20200119101107820](/images/spring/image-20200119101107820.png)
### 使用阶段(调用阶段)
在`org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])`中有如下代码
```JAVA
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
```
- `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation`
```JAVA
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
/**
* 主要实现{@link org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(java.lang.Class, java.lang.String)}
*/
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
```
- `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation`
```JAVA
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 调用自定义实现
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
```
这个地方已经可以看到`InstantiationAwareBeanPostProcessor`出现了,并且调用了方法`postProcessBeforeInstantiation`,此处就可以调用我们的自定义方法了
![image-20200119101516591](/images/spring/image-20200119101516591.png)

@ -0,0 +1,278 @@
# DefaultSingletonBeanRegistry
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
- 源码路径: `org.springframework.beans.factory.support.DefaultSingletonBeanRegistry`
- 官方提供的测试类: `org.springframework.beans.factory.support.DefaultSingletonBeanRegistryTests`
类图
![image-20200110093044672](/images/spring/image-20200110093044672.png)
## 注册方法解析
- 从名字可以看出这是一个单例对象的注册类
- `org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.registerSingleton`
- 测试用例出发
```java
@Test
public void testSingletons() {
DefaultSingletonBeanRegistry beanRegistry = new DefaultSingletonBeanRegistry();
TestBean tb = new TestBean();
beanRegistry.registerSingleton("tb", tb);
assertSame(tb, beanRegistry.getSingleton("tb"));
TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return new TestBean();
}
});
assertSame(tb2, beanRegistry.getSingleton("tb2"));
assertSame(tb, beanRegistry.getSingleton("tb"));
assertSame(tb2, beanRegistry.getSingleton("tb2"));
assertEquals(2, beanRegistry.getSingletonCount());
String[] names = beanRegistry.getSingletonNames();
assertEquals(2, names.length);
assertEquals("tb", names[0]);
assertEquals("tb2", names[1]);
beanRegistry.destroySingletons();
assertEquals(0, beanRegistry.getSingletonCount());
assertEquals(0, beanRegistry.getSingletonNames().length);
}
```
- 第一个关注的方法`org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerSingleton` 注册单例对象
```java
/**
* 注册一个单例对象
*
* @param beanName the name of the bean
* @param singletonObject the existing singleton object
* @throws IllegalStateException
*/
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
// 通过beanName获取单例对象
Object oldObject = this.singletonObjects.get(beanName);
// 不为空异常
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
// 添加方法
addSingleton(beanName, singletonObject);
}
}
```
```java
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* <p>
* 添加单例对象的操作方法
*
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
```
- 这些变量是什么
```java
/**
* 单例对象的缓存: beanName -> Object
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/**
* 单例工厂的缓存: beanName -> ObjectFactory。
*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/**
* 延迟加载的单例对象缓存: beanName -> Object
*/
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/**
* 已经注册过的单例对象名称(beanName)
*/
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/**
* 当前正在创建的单例对象名称(beanName)
*/
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* 摧毁单例对象
*/
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
/**
* bean 和beanName的关系
*/
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/**
* bean 依赖关系 beanName -> 依赖关系
*/
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
/**
* 异常列表
*/
@Nullable
private Set<Exception> suppressedExceptions;
/**
* 标记是否在 destroySingletons 上
*/
private boolean singletonsCurrentlyInDestruction = false;
```
- 注册方法至此结束
## 获取方法解析
- `org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(java.lang.String)`
```java
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
```
```java
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从列表中获取单例对象
Object singletonObject = this.singletonObjects.get(beanName);
// 判断当前beanName是否存在
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 从延迟加载中获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 从singletonFactories获取ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 获取对象
singletonObject = singletonFactory.getObject();
// 加入缓存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
```
- 获取单例对象的本质就是从map中获取 ObjectFactory 进而执行 getObject()
`ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);`
- 测试方法
```java
TestBean tb2 = (TestBean) beanRegistry.getSingleton("tb2", new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return new TestBean();
}
});
```
- 获取单例对象的方式
```java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 从单例对象中获取一个对象
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 调用自定义实现,或者接口实现
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
```
不难发现最后都是通过`singletonObject = singletonFactory.getObject();`进行获取
这个地方的方法实际上就是测试类中的
```java
new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return new TestBean();
}
}
```
通过`getObject`就可以获取当前对象

@ -0,0 +1,98 @@
# Spring OrderComparator
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
```java
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
boolean p1 = (o1 instanceof PriorityOrdered);
boolean p2 = (o2 instanceof PriorityOrdered);
if (p1 && !p2) {
return -1;
} else if (p2 && !p1) {
return 1;
}
int i1 = getOrder(o1, sourceProvider);
int i2 = getOrder(o2, sourceProvider);
// 对比两个Order值得大小返回
return Integer.compare(i1, i2);
}
```
```java
private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
Integer order = null;
if (obj != null && sourceProvider != null) {
// 获取Order
Object orderSource = sourceProvider.getOrderSource(obj);
if (orderSource != null) {
if (orderSource.getClass().isArray()) {
// 获取 OrderSourceProvider 的值
Object[] sources = ObjectUtils.toObjectArray(orderSource);
for (Object source : sources) {
// 找 order 返回
order = findOrder(source);
if (order != null) {
break;
}
}
} else {
// 寻找 order
order = findOrder(orderSource);
}
}
}
return (order != null ? order : getOrder(obj));
}
```
- 测试用例
```java
@Test
public void compareWithSourceProviderArray() {
Comparator<Object> customComparator = this.comparator.withSourceProvider(
new TestSourceProvider(5L, new Object[]{new StubOrdered(10), new StubOrdered(-25)}));
assertEquals(-1, customComparator.compare(5L, new Object()));
}
```
![image-20200116141838601](/images/spring/image-20200116141838601.png)
```java
@Nullable
protected Integer findOrder(Object obj) {
// 获取Ordered实现类
return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
}
```
```java
private static final class StubOrdered implements Ordered {
private final int order;
public StubOrdered(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
}
```
![image-20200116141932486](/images/spring/image-20200116141932486.png)
最终`Integer.compare(i1, i2)`比较返回 OK !

@ -0,0 +1,534 @@
# Spring scan
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
## 解析
- Spring 注解形式使用有下面两种方式
1. 通过`AnnotationConfigApplicationContext`参数:扫描包
2. 通过xml配置`context:component-scan`属性`base-package`
```java
AnnotationConfigApplicationContext aac =
new AnnotationConfigApplicationContext("com.huifer.source.spring.ann");
```
```xml
<context:component-scan base-package="com.huifer.source.spring.ann">
</context:component-scan>
```
- 目标明确开始找入口方法
- `AnnotationConfigApplicationContext`直接点进去看就找到了
```java
public AnnotationConfigApplicationContext(String... basePackages) {
this();
// 扫描包
scan(basePackages);
refresh();
}
```
- `context:component-scan`寻找方式:冒号`:`钱+NamespaceHandler 或者全文搜索`component-scan`,最终找到`org.springframework.context.config.ContextNamespaceHandler`
```java
public class ContextNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
}
```
### org.springframework.context.annotation.ComponentScanBeanDefinitionParser
![image-20200115093602651](/images/spring/image-20200115093602651.png)
- 实现`BeanDefinitionParser`直接看`parse`方法
```java
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 获取 base-package 属性值
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
// 处理 ${}
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
// 分隔符`,;\t\n`切分
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// Actually scan for bean definitions and register them.
// 扫描对象创建
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
// 执行扫描方法
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
// 注册组件,触发监听
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
```
- 回过头看`AnnotationConfigApplicationContext`
### org.springframework.context.annotation.AnnotationConfigApplicationContext
```java
public AnnotationConfigApplicationContext(String... basePackages) {
this();
// 扫描包
scan(basePackages);
refresh();
}
```
```java
private final ClassPathBeanDefinitionScanner scanner;
@Override
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.scanner.scan(basePackages);
}
```
- `org.springframework.context.annotation.ClassPathBeanDefinitionScanner.scan`
```java
public int scan(String... basePackages) {
// 获取bean数量
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// 执行扫描
doScan(basePackages);
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
```
- 这个地方`doScan`似曾相识,他就是`org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse`中的`doScan`,下一步解析doScan
### org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan
```java
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// 寻找组件
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// bean 作用域设置
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
// 设置生命周期
candidate.setScope(scopeMetadata.getScopeName());
// 创建beanName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
// 设置默认属性 具体方法:org.springframework.beans.factory.support.AbstractBeanDefinition.applyDefaults
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 读取LazyPrimary 等注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// bean的重复检查
if (checkCandidate(beanName, candidate)) {
// 创建 BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 代理对象的处理
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 放入list中,最后返回用
beanDefinitions.add(definitionHolder);
// 注册bean
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
```
#### org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents
```java
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
// 扫描
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
return scanCandidateComponents(basePackage);
}
}
```
```java
/**
* 扫描当前包路径下的资源
* @param basePackage
* @return
*/
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// 字符串拼接出一个编译后的路径 classpath://
// 这里替换了通配符
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// 获取资源
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
// 日志级别
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
// 获取 MetadataReader
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
// 判断是否是 Component
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
```
#### org.springframework.context.annotation.ScopeMetadataResolver#resolveScopeMetadata
```java
/**
* 生命周期设置
*
* @param definition the target bean definition
* @return
*/
@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
// 判断是否属于 AnnotatedBeanDefinition
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
annDef.getMetadata(), this.scopeAnnotationType);
if (attributes != null) {
// 获取 value 属性值并且设置
metadata.setScopeName(attributes.getString("value"));
// 获取 proxyMode 属性值并且设置
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = this.defaultProxyMode;
}
metadata.setScopedProxyMode(proxyMode);
}
}
return metadata;
}
```
- `org.springframework.context.annotation.AnnotationScopeMetadataResolverTests#resolveScopeMetadataShouldReadScopedProxyModeFromAnnotation`测试用例
```java
@Test
public void resolveScopeMetadataShouldReadScopedProxyModeFromAnnotation() {
AnnotatedBeanDefinition bd = new AnnotatedGenericBeanDefinition(AnnotatedWithScopedProxy.class);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(bd);
assertNotNull("resolveScopeMetadata(..) must *never* return null.", scopeMetadata);
assertEquals("request", scopeMetadata.getScopeName());
assertEquals(TARGET_CLASS, scopeMetadata.getScopedProxyMode());
}
```
![image-20200115141708702](/images/spring/image-20200115141708702.png)
#### org.springframework.beans.factory.support.BeanNameGenerator#generateBeanName
- 创建beanName `org.springframework.context.annotation.AnnotationBeanNameGenerator#generateBeanName`
```java
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
if (definition instanceof AnnotatedBeanDefinition) {
// 如果存在bean(value="") value存在
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
// Explicit bean name found.
return beanName;
}
}
// Fallback: generate a unique default bean name.
// 创建beanName
return buildDefaultBeanName(definition, registry);
}
```
```java
@Nullable
protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
AnnotationMetadata amd = annotatedDef.getMetadata();
Set<String> types = amd.getAnnotationTypes();
String beanName = null;
for (String type : types) {
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
if (attributes != null && isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
// 获取注解的value 属性值
Object value = attributes.get("value");
if (value instanceof String) {
String strVal = (String) value;
// 判断是否存在值
if (StringUtils.hasLength(strVal)) {
if (beanName != null && !strVal.equals(beanName)) {
throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
"component names: '" + beanName + "' versus '" + strVal + "'");
}
// beanName = value属性值
beanName = strVal;
}
}
}
}
return beanName;
}
```
```java
@Service(value = "dhc")
public class DemoService {
}
```
![image-20200115143315633](/images/spring/image-20200115143315633.png)
- `org.springframework.context.annotation.AnnotationBeanNameGenerator#buildDefaultBeanName(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry)`
- `org.springframework.context.annotation.AnnotationBeanNameGenerator#buildDefaultBeanName(org.springframework.beans.factory.config.BeanDefinition)`
```JAVA
protected String buildDefaultBeanName(BeanDefinition definition) {
// 获取bean class name
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
// 获取短类名,
String shortClassName = ClassUtils.getShortName(beanClassName);
// 第一个字母小写
return Introspector.decapitalize(shortClassName);
}
```
```JAVA
@Configuration
public class BeanConfig {
@Scope(value =ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean(value = "hc")
public Ubean f() {
return new Ubean();
}
}
```
![image-20200115143456554](/images/spring/image-20200115143456554.png)
#### org.springframework.context.annotation.ClassPathBeanDefinitionScanner#postProcessBeanDefinition
- 这个方法没什么难点直接是set方法
```java
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
beanDefinition.applyDefaults(this.beanDefinitionDefaults);
if (this.autowireCandidatePatterns != null) {
beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
}
}
```
```java
public void applyDefaults(BeanDefinitionDefaults defaults) {
setLazyInit(defaults.isLazyInit());
setAutowireMode(defaults.getAutowireMode());
setDependencyCheck(defaults.getDependencyCheck());
setInitMethodName(defaults.getInitMethodName());
setEnforceInitMethod(false);
setDestroyMethodName(defaults.getDestroyMethodName());
setEnforceDestroyMethod(false);
}
```
#### org.springframework.context.annotation.AnnotationConfigUtils#processCommonDefinitionAnnotations(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition)
```java
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
processCommonDefinitionAnnotations(abd, abd.getMetadata());
}
```
```java
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
// 获取 lazy 注解
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
} else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
abd.setRole(role.getNumber("value").intValue());
}
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
abd.setDescription(description.getString("value"));
}
}
```
- 方法思路:
1. 获取注解的属性值
2. 设置注解属性
#### org.springframework.context.annotation.ClassPathBeanDefinitionScanner#checkCandidate
- 重复检查
```java
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
// 判断当前 beanName 是否在注册表中
if (!this.registry.containsBeanDefinition(beanName)) {
return true;
}
// 从注册表中获取
BeanDefinition existingDef = this.registry.getBeanDefinition(beanName);
// 当前的bean
BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition();
if (originatingDef != null) {
existingDef = originatingDef;
}
if (isCompatible(beanDefinition, existingDef)) {
return false;
}
throw new ConflictingBeanDefinitionException("Annotation-specified bean name '" + beanName +
"' for bean class [" + beanDefinition.getBeanClassName() + "] conflicts with existing, " +
"non-compatible bean definition of same name and class [" + existingDef.getBeanClassName() + "]");
}
```
#### org.springframework.context.annotation.AnnotationConfigUtils#applyScopedProxyMode
```JAVA
static BeanDefinitionHolder applyScopedProxyMode(
ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
return definition;
}
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
// 创建代理对象
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
```

@ -0,0 +1,658 @@
# Spring 自定义标签解析
- Author: [HuiFer](https://github.com/huifer)
- 源码阅读仓库: [huifer-spring](https://github.com/huifer/spring-framework-read)
- 与自定义标签解析相关的类
1. `org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser`
2. `org.springframework.beans.factory.xml.NamespaceHandlerSupport`
- 开始源码之前先搭建一个环境
## 环境搭建
- 创建对象
```java
public class UserXtd {
private String userName;
private String emailAddress;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
}
```
- 创建 xsd 文件
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.huifer.com/schema/user"
elementFormDefault="qualified">
<element name="myUser">
<complexType>
<attribute name="id" type="string"/>
<attribute name="userName" type="string"/>
<attribute name="emailAddress" type="string"/>
</complexType>
</element>
</schema>
```
- 创建 namespaceHandler
```java
public class UserNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("myUser", new UserBeanDefinitionParser());
}
}
```
- 创建 beanDefinitionParser
```java
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
/**
* 标签对应class
* @param element the {@code Element} that is being parsed
* @return
*/
@Override
protected Class<?> getBeanClass(Element element) {
return UserXtd.class;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
// 获取 userName 标签属性值
String name = element.getAttribute("userName");
// 获取 emailAddress 标签属性值
String address = element.getAttribute("emailAddress");
if (StringUtils.hasText(name)) {
builder.addPropertyValue("userName", name);
}
if (StringUtils.hasText(address)) {
builder.addPropertyValue("emailAddress", address);
}
}
}
```
- 创建 resource/META-INF/spring.handlers
```text
http\://www.huifer.com/schema/user=com.huifer.source.spring.parser.UserNamespaceHandler
```
- 创建 resource/META-INF/spring.schemas
```text
http\://www.huifer.com/schema/user.xsd=META-INF/spring-test.xsd
```
- 创建测试用例xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:myname="http://www.huifer.com/schema/user"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.huifer.com/schema/user http://www.huifer.com/schema/user.xsd
">
<myname:myUser id="testUserBean" userName="huifer" emailAddress="huifer97@163.com"/>
</beans>
```
- 创建 Java 运行方法
```java
/**
* 自定义标签测试用例
*/
public class XSDDemo {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("XTD-xml.xml");
UserXtd user = (UserXtd) applicationContext.getBean("testUserBean");
System.out.println(user.getEmailAddress());
}
}
```
- 这里我们希望输出结果是`huifer97@163.com`,运行后结果也确实是`huifer97@163.com`
## 解析 DefaultNamespaceHandlerResolver
- 入口方法`org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions`
```java
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
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)) {
// 不同标签的解析
parseDefaultElement(ele, delegate);
}
else {
// 非spring 默认标签解析
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
```
- 调用链路
- `org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(org.w3c.dom.Element)`
- `org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)`
```java
/**
* Parse a custom element (outside of the default namespace).
* <p>
* 自定义标签解析
*
* @param ele the element to parse
* @param containingBd the containing bean definition (if any)
* @return the resulting bean definition
*/
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
// 自定义标签解析
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 根据命名空间获取处理类
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 自定义处理器
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
```
![image-20200109084131415](/images/spring/image-20200109084131415.png)
- `http://www.huifer.com/schema/user`和我们定义的xsd文件中的url相同如何找到对应的NamespaceHandler,在`META-INF/spring.handlers`中有定义,
`http\://www.huifer.com/schema/user=com.huifer.source.spring.parser.UserNamespaceHandler`
`NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);`这行代码就是获取`spring.handlers`中的定义
- 处理方法`org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve`
```java
/**
* Locate the {@link NamespaceHandler} for the supplied namespace URI
* from the configured mappings.
*
* 根据 namespaceUri 获取对应的 {@link NamespaceHandler}
* @param namespaceUri the relevant namespace URI
* @return the located {@link NamespaceHandler}, or {@code null} if none found
*/
@Override
@Nullable
public NamespaceHandler resolve(String namespaceUri) {
// 获取handlerMapping
Map<String, Object> handlerMappings = getHandlerMappings();
// 从 handlerMapping 中获取类名
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
// 判断是否处理过,处理过直接返回
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
else {
// 没有处理,进行反射还原类
String className = (String) handlerOrClassName;
try {
// 通过反射还原类
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
// 初始化类
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
// 调用init()方法,自定义类中实现
namespaceHandler.init();
// 放入缓存
handlerMappings.put(namespaceUri, namespaceHandler);
// 返回自定义的 namespaceHandler
return namespaceHandler;
}
catch (ClassNotFoundException ex) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
"] for namespace [" + namespaceUri + "]", ex);
}
catch (LinkageError err) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
```
- `org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#getHandlerMappings`跟踪这个方法
```JAVA
/**
* Load the specified NamespaceHandler mappings lazily.
*
* 获取handlerMappings
*/
private Map<String, Object> getHandlerMappings() {
Map<String, Object> handlerMappings = this.handlerMappings;
}
```
![image-20200109085606240](/images/spring/image-20200109085606240.png)
- 这里直接存在数据了,他是从什么时候加载的?
- `org.springframework.beans.factory.xml.XmlBeanDefinitionReader#registerBeanDefinitions`
这个方法在注册bean定义的时候调用
```java
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
// 注册方法
// createReaderContext 初始化HandlerMapping
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
```
- 继续跟踪`createReaderContext`
```java
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#createReaderContext
```
```java
public XmlReaderContext createReaderContext(Resource resource) {
return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
this.sourceExtractor, this, getNamespaceHandlerResolver());
}
```
- 继续跟踪`getNamespaceHandlerResolver`
`org.springframework.beans.factory.xml.XmlBeanDefinitionReader#getNamespaceHandlerResolver`
```java
public NamespaceHandlerResolver getNamespaceHandlerResolver() {
if (this.namespaceHandlerResolver == null) {
this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
}
return this.namespaceHandlerResolver;
}
```
- 继续跟踪`createDefaultNamespaceHandlerResolver`
`org.springframework.beans.factory.xml.XmlBeanDefinitionReader#createDefaultNamespaceHandlerResolver`
```java
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader());
return new DefaultNamespaceHandlerResolver(cl);
}
```
- 继续跟踪`DefaultNamespaceHandlerResolver`
`org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver`
```java
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader) {
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
```
他回到了我们之前疑问的地方 `handlerMappings` 如何出现的
断点
![image-20200109090456547](/images/spring/image-20200109090456547.png)
```JAVA
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader) {
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
```
`public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";`
![image-20200109090655157](/images/spring/image-20200109090655157.png)
此时还是空
走完
![image-20200109091216505](/images/spring/image-20200109091216505.png)
```java
@Override
public String toString() {
return "NamespaceHandlerResolver using mappings " + getHandlerMappings();
}
```
```JAVA
/**
* Load the specified NamespaceHandler mappings lazily.
*
* 获取handlerMappings
*/
private Map<String, Object> getHandlerMappings() {
Map<String, Object> handlerMappings = this.handlerMappings;
// 缓存不存在
if (handlerMappings == null) {
synchronized (this) {
handlerMappings = this.handlerMappings;
if (handlerMappings == null) {
if (logger.isTraceEnabled()) {
logger.trace("Loading NamespaceHandler mappings from [" + this.handlerMappingsLocation + "]");
}
try {
// 将本地文件读出
Properties mappings =
PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
if (logger.isTraceEnabled()) {
logger.trace("Loaded NamespaceHandler mappings: " + mappings);
}
handlerMappings = new ConcurrentHashMap<>(mappings.size());
// 转换成map结构
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
this.handlerMappings = handlerMappings;
}
catch (IOException ex) {
throw new IllegalStateException(
"Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex);
}
}
}
}
return handlerMappings;
}
```
![image-20200109094032421](/images/spring/image-20200109094032421.png)
## org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver#resolve
```java
@Override
@Nullable
public NamespaceHandler resolve(String namespaceUri) {
// 获取handlerMapping
Map<String, Object> handlerMappings = getHandlerMappings();
// 从 handlerMapping 中获取类名
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
// 判断是否处理过,处理过直接返回
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
else {
// 没有处理,进行反射还原类
String className = (String) handlerOrClassName;
try {
// 通过反射还原类
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
// 初始化类
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
// 调用init()方法,自定义类中实现
namespaceHandler.init();
// 放入缓存
handlerMappings.put(namespaceUri, namespaceHandler);
// 返回自定义的 namespaceHandler
return namespaceHandler;
}
catch (ClassNotFoundException ex) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
"] for namespace [" + namespaceUri + "]", ex);
}
catch (LinkageError err) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
```
执行`init`方法
```java
public class UserNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("myUser", new UserBeanDefinitionParser());
}
}
```
```java
/**
* Subclasses can call this to register the supplied {@link BeanDefinitionParser} to
* handle the specified element. The element name is the local (non-namespace qualified)
* name.
*
* 将标签名称,标签解析类放入
*/
protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
this.parsers.put(elementName, parser);
}
```
- 方法走完,回到开始的方法
```java
/**
* Parse a custom element (outside of the default namespace).
* <p>
* 自定义标签解析
*
* @param ele the element to parse
* @param containingBd the containing bean definition (if any)
* @return the resulting bean definition
*/
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
// 自定义标签解析
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 根据命名空间获取处理类
// org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 自定义处理器
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
```
![image-20200109092801572](/images/spring/image-20200109092801572.png)
## org.springframework.beans.factory.xml.NamespaceHandler#parse
- `org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse`
```java
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinitionParser parser = findParserForElement(element, parserContext);
return (parser != null ? parser.parse(element, parserContext) : null);
}
```
### org.springframework.beans.factory.xml.NamespaceHandlerSupport#findParserForElement
```java
@Nullable
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
// 获取标签名称
String localName = parserContext.getDelegate().getLocalName(element);
// 在map中获取对应的标签解析类
BeanDefinitionParser parser = this.parsers.get(localName);
// 空报错
if (parser == null) {
parserContext.getReaderContext().fatal(
"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
}
// 不为空返回
return parser;
}
```
![image-20200109093242494](/images/spring/image-20200109093242494.png)
### org.springframework.beans.factory.xml.BeanDefinitionParser#parse
- `org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parse`
```java
public final BeanDefinition parse(Element element, ParserContext parserContext) {
/**
* {@link AbstractSingleBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)}
*/
AbstractBeanDefinition definition = parseInternal(element, parserContext);
}
```
### org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#parseInternal
```java
@Override
protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
String parentName = getParentName(element);
if (parentName != null) {
builder.getRawBeanDefinition().setParentName(parentName);
}
// 调用自己实现的方法 com.huifer.source.spring.parser.UserBeanDefinitionParser.getBeanClass
Class<?> beanClass = getBeanClass(element);
if (beanClass != null) {
builder.getRawBeanDefinition().setBeanClass(beanClass);
}
else {
// getBeanClassName 同样也是可以在自定义的解析类中实现
String beanClassName = getBeanClassName(element);
if (beanClassName != null) {
builder.getRawBeanDefinition().setBeanClassName(beanClassName);
}
}
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
BeanDefinition containingBd = parserContext.getContainingBeanDefinition();
if (containingBd != null) {
// Inner bean definition must receive same scope as containing bean.
// 设置scope
builder.setScope(containingBd.getScope());
}
if (parserContext.isDefaultLazyInit()) {
// Default-lazy-init applies to custom bean definitions as well.
// 设置 lazy-init
builder.setLazyInit(true);
}
// 执行解析方法,在自定义解析类中存在com.huifer.source.spring.parser.UserBeanDefinitionParser.doParse
doParse(element, parserContext, builder);
return builder.getBeanDefinition();
}
```
![image-20200109094654409](/images/spring/image-20200109094654409.png)
执行`com.huifer.source.spring.parser.UserBeanDefinitionParser#doParse`
```JAVA
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
// 获取 userName 标签属性值
String name = element.getAttribute("userName");
// 获取 emailAddress 标签属性值
String address = element.getAttribute("emailAddress");
if (StringUtils.hasText(name)) {
builder.addPropertyValue("userName", name);
}
if (StringUtils.hasText(address)) {
builder.addPropertyValue("emailAddress", address);
}
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Loading…
Cancel
Save