@ -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/>
|
||||
```
|
||||
- 源码阅读目标找到了,那么怎么去找入口或者对这句话的标签解析方法呢?项目中使用搜索
|
||||
|
||||

|
||||
|
||||
这样就找到了具体解析方法了
|
||||
|
||||
### `org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser`
|
||||
|
||||
- 类图
|
||||
|
||||

|
||||
```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,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;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
- 该类给`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
|
||||
|
||||

|
||||
|
||||
- annotationType
|
||||
|
||||

|
||||
|
||||
```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);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
处理结果
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
处理结果和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;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
最终返回
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 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;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
- `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();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 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
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
- 注册方法信息截图
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 使用阶段(调用阶段)
|
||||
|
||||
在`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`,此处就可以调用我们的自定义方法了
|
||||
|
||||

|
||||
@ -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`
|
||||
|
||||
类图
|
||||

|
||||
## 注册方法解析
|
||||
- 从名字可以看出这是一个单例对象的注册类
|
||||
- `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()));
|
||||
}
|
||||
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
```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;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
最终`Integer.compare(i1, i2)`比较返回 OK !
|
||||
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 42 KiB |