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