From aab986b28ca38e610194b948a27a283982e245f1 Mon Sep 17 00:00:00 2001 From: senntyou Date: Fri, 22 Oct 2021 11:31:15 +0800 Subject: [PATCH] add spring/9 --- README.md | 1 + spring/9.md | 837 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 838 insertions(+) create mode 100644 spring/9.md diff --git a/README.md b/README.md index c52b4f6..a086700 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ 1. [\[2021-10-20\] Spring 源码解析六:处理器映射与处理器适配处理](spring/6.md) 1. [\[2021-10-21\] Spring 源码解析七:异常处理与视图解析](spring/7.md) 1. [\[2021-10-21\] Spring 源码解析八:Xml 配置中默认的命名空间处理器](spring/8.md) +1. [\[2021-10-21\] Spring 源码解析九:默认的注解处理器](spring/9.md) ## 前端进阶 diff --git a/spring/9.md b/spring/9.md new file mode 100644 index 0000000..765f330 --- /dev/null +++ b/spring/9.md @@ -0,0 +1,837 @@ +# Spring 源码解析九:默认的注解处理器 + +在 [Spring 源码解析五:Bean 的配置、定义、注册](./5.md) 中,有一些默认的注解处理器还未解析 + +- [ConfigurationClassPostProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java) +- [AutowiredAnnotationBeanPostProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java) +- [CommonAnnotationBeanPostProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java) +- [PersistenceAnnotationBeanPostProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java) +- [EventListenerMethodProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java) +- [DefaultEventListenerFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/event/DefaultEventListenerFactory.java) + +## 1. ConfigurationClassPostProcessor + +[ConfigurationClassPostProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java) +的主要功能是处理`@Configuration`类 + +```java +public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, + PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware { + // 后置处理registry + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { + // ... 代码省略 + + // 处理配置类bean定义 + processConfigBeanDefinitions(registry); + } + + // 后置处理registry + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { + // ... 代码省略 + + // 处理配置类bean定义 + processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); + + // 使用ConfigurationClassEnhancer对@Configuration的class进行cglib增强 + enhanceConfigurationClasses(beanFactory); + + // ... 代码省略 + } +} +``` + +```java +public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, + PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware { + // 处理配置类bean定义 + public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { + // 配置类集合 + List configCandidates = new ArrayList<>(); + // 所有bean的名字 + String[] candidateNames = registry.getBeanDefinitionNames(); + + // 遍历 + for (String beanName : candidateNames) { + // 获取bean定义 + BeanDefinition beanDef = registry.getBeanDefinition(beanName); + + // ... 代码省略 + + // 如果是@Configuration标记的类,加入集合 + if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { + configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); + } + } + + // 没有@Configuration标记的类,返回 + if (configCandidates.isEmpty()) { + return; + } + + // ... 代码省略 + + // 获取 @Configuration 类解析器 + ConfigurationClassParser parser = new ConfigurationClassParser( + this.metadataReaderFactory, this.problemReporter, this.environment, + this.resourceLoader, this.componentScanBeanNameGenerator, registry); + + // 待解析集合 + Set candidates = new LinkedHashSet<>(configCandidates); + // 已解析集合 + Set alreadyParsed = new HashSet<>(configCandidates.size()); + do { + // ... 代码省略 + + // 解析配置类 + parser.parse(candidates); + // 验证配置类 + parser.validate(); + + // 获取所有的配置类,包括以前注册的 + Set configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); + // 移除已解析的 + configClasses.removeAll(alreadyParsed); + + if (this.reader == null) { + // 使用ConfigurationClassBeanDefinitionReader创建配置类bean定义读取器 + this.reader = new ConfigurationClassBeanDefinitionReader( + registry, this.sourceExtractor, this.resourceLoader, this.environment, + this.importBeanNameGenerator, parser.getImportRegistry()); + } + // 读取bean定义 + this.reader.loadBeanDefinitions(configClasses); + // 添加到已解析 + alreadyParsed.addAll(configClasses); + + // ... 代码省略 + } + while (!candidates.isEmpty()); + + // ... 代码省略 + } +} +``` + +对`@Configuration`类的处理核心是 [ConfigurationClassParser](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java) +实现的 + +```java +class ConfigurationClassParser { + public void parse(Set configCandidates) { + for (BeanDefinitionHolder holder : configCandidates) { + BeanDefinition bd = holder.getBeanDefinition(); + try { + // AnnotatedBeanDefinition处理 + if (bd instanceof AnnotatedBeanDefinition) { + parse1(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); + } + // AbstractBeanDefinition+beanClass处理 + else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { + parse2(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); + } + // 默认处理 + else { + parse3(bd.getBeanClassName(), holder.getBeanName()); + } + } + catch (BeanDefinitionStoreException ex) { + // ... 代码省略 + } + // ... 代码省略 + } + + // ... 代码省略 + } + + protected final void parse1(AnnotationMetadata metadata, String beanName) throws IOException { + processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER); + } + + protected final void parse2(Class clazz, String beanName) throws IOException { + processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER); + } + + protected final void parse3(@Nullable String className, String beanName) throws IOException { + MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className); + processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER); + } +} +``` + +```java +class ConfigurationClassParser { + protected void processConfigurationClass(ConfigurationClass configClass, Predicate filter) throws IOException { + // ... 代码省略 + + // 包裹成SourceClass + SourceClass sourceClass = asSourceClass(configClass, filter); + // 遍历处理配置类,及其父类 + do { + sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter); + } + while (sourceClass != null); + + // ... 代码省略 + } + + // 处理配置类 + protected final SourceClass doProcessConfigurationClass( + ConfigurationClass configClass, SourceClass sourceClass, Predicate filter) + throws IOException { + + // 处理@Component注解 + if (configClass.getMetadata().isAnnotated(Component.class.getName())) { + // 遍历处理内部类(非静态内部类) + processMemberClasses(configClass, sourceClass, filter); + } + + // 处理@PropertySource注解,装载属性都bean中 + for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( + sourceClass.getMetadata(), PropertySources.class, + org.springframework.context.annotation.PropertySource.class)) { + // 装载属性都bean中 + processPropertySource(propertySource); + } + + // 处理@ComponentScan注解,扫描指定的包 + Set componentScans = AnnotationConfigUtils.attributesForRepeatable( + sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); + if (!componentScans.isEmpty() && + !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { + // 遍历扫描 + for (AnnotationAttributes componentScan : componentScans) { + // 扫描到的bean定义 + Set scannedBeanDefinitions = + this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); + // 遍历bean定义 + for (BeanDefinitionHolder holder : scannedBeanDefinitions) { + BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); + // 如果也标记有@Configuration,继续解析 + if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { + parse(bdCand.getBeanClassName(), holder.getBeanName()); + } + } + } + } + + // 处理@Import注解 + processImports(configClass, sourceClass, getImports(sourceClass), filter, true); + + // 处理@ImportResource注解 + AnnotationAttributes importResource = + AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); + if (importResource != null) { + // ... 代码省略 + } + + // 处理类中标记为@Bean的方法 + Set beanMethods = retrieveBeanMethodMetadata(sourceClass); + for (MethodMetadata methodMetadata : beanMethods) { + configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); + } + + // 如果类是接口,注入默认的方法 + processInterfaces(configClass, sourceClass); + + // 如果有父类,返回父类,继续遍历 + if (sourceClass.getMetadata().hasSuperClass()) { + // ... 代码省略 + } + + // 没有父类,结束遍历 + return null; + } +} +``` + +## 2. AutowiredAnnotationBeanPostProcessor + +[ConfigurationClassPostProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java) +的主要功能是处理 bean 的自动装配 + +```java +public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, + MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { + // 默认处理@Autowired、@Value、@Inject三个注解 + public AutowiredAnnotationBeanPostProcessor() { + this.autowiredAnnotationTypes.add(Autowired.class); + this.autowiredAnnotationTypes.add(Value.class); + try { + this.autowiredAnnotationTypes.add((Class) + ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); + } + catch (ClassNotFoundException ex) { + // ... 代码省略 + } + } + + // 处理属性注入 + @Override + public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { + // 查找需要注入的元信息 + InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); + try { + // 注入 + metadata.inject(bean, beanName, pvs); + } + catch (BeanCreationException ex) { + // ... 代码省略 + } + + return pvs; + } + + // 查找需要注入的元信息 + private InjectionMetadata findAutowiringMetadata(String beanName, Class clazz, @Nullable PropertyValues pvs) { + // 加锁的方式取出 + InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); + if (InjectionMetadata.needsRefresh(metadata, clazz)) { + synchronized (this.injectionMetadataCache) { + metadata = this.injectionMetadataCache.get(cacheKey); + if (InjectionMetadata.needsRefresh(metadata, clazz)) { + if (metadata != null) { + metadata.clear(pvs); + } + // 构建元信息 + metadata = buildAutowiringMetadata(clazz); + this.injectionMetadataCache.put(cacheKey, metadata); + } + } + } + return metadata; + } +} +``` + +```java +public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, + MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { + // 构建元信息 + private InjectionMetadata buildAutowiringMetadata(final Class clazz) { + // ... 代码省略 + + // 注入元素集合 + List elements = new ArrayList<>(); + Class targetClass = clazz; + + do { + // 当前元素集合 + final List currElements = new ArrayList<>(); + // 遍历本地属性 + ReflectionUtils.doWithLocalFields(targetClass, field -> { + // 获取@Autowired、@Value、@Inject注解 + MergedAnnotation ann = findAutowiredAnnotation(field); + if (ann != null) { + if (Modifier.isStatic(field.getModifiers())) { + // 静态属性不能注入 + return; + } + // required 配置 + boolean required = determineRequiredStatus(ann); + // 加入属性元素 + currElements.add(new AutowiredFieldElement(field, required)); + } + }); + + // 遍历本地方法 + ReflectionUtils.doWithLocalMethods(targetClass, method -> { + Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); + + // ... 代码省略 + + // 获取@Autowired、@Value、@Inject注解 + MergedAnnotation ann = findAutowiredAnnotation(bridgedMethod); + if (ann != null) { + if (Modifier.isStatic(method.getModifiers())) { + // 静态方法不能注入 + return; + } + + // required 配置 + boolean required = determineRequiredStatus(ann); + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); + // 加入方法元素 + currElements.add(new AutowiredMethodElement(method, required, pd)); + } + }); + + // 添加进注入元素集合 + elements.addAll(0, currElements); + // 遍历父类 + targetClass = targetClass.getSuperclass(); + } + while (targetClass != null && targetClass != Object.class); + + return InjectionMetadata.forElements(elements, clazz); + } +} +``` + +属性的注入是 `AutowiredFieldElement.inject` 完成的,方法参数的注入是 `AutowiredMethodElement.inject` 完成的 + +```java +private class AutowiredFieldElement extends InjectionMetadata.InjectedElement { + @Override + protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { + Field field = (Field) this.member; + Object value; + if (this.cached) { + // 先从缓存中获取bean,其次从registry获取bean + value = resolvedCachedArgument(beanName, this.cachedFieldValue); + } + else { + // 实例化一个DependencyDescriptor对象 + DependencyDescriptor desc = new DependencyDescriptor(field, this.required); + + // ... 代码省略 + + try { + // 从registry获取bean + value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); + } + catch (BeansException ex) { + // ... 代码省略 + } + synchronized (this) { + // ... 代码省略 + + // 把autowiredBeanNames注册为beanName的依赖 + registerDependentBeans(beanName, autowiredBeanNames); + + // ... 代码省略 + } + } + // 把bean注入到属性中 + if (value != null) { + ReflectionUtils.makeAccessible(field); + field.set(bean, value); + } + } +} +``` + +```java +private class AutowiredMethodElement extends InjectionMetadata.InjectedElement { + @Override + protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { + // ... 代码省略 + + Method method = (Method) this.member; + Object[] arguments; + if (this.cached) { + // 先从缓存中获取参数bean集合,其次从registry获取参数bean集合 + arguments = resolveCachedArguments(beanName); + } + else { + // 参数个数 + int argumentCount = method.getParameterCount(); + // 参数集合 + arguments = new Object[argumentCount]; + + // ... 代码省略 + + for (int i = 0; i < arguments.length; i++) { + // 参数对象 + MethodParameter methodParam = new MethodParameter(method, i); + + // ... 代码省略 + + try { + // 获取参数注入的bean + Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter); + + // ... 代码省略 + + arguments[i] = arg; + } + catch (BeansException ex) { + // ... 代码省略 + } + } + + // ... 代码省略 + } + // 把bean注入到参数中 + if (arguments != null) { + try { + ReflectionUtils.makeAccessible(method); + method.invoke(bean, arguments); + } + catch (InvocationTargetException ex) { + // ... 代码省略 + } + } + } +} +``` + +## 3. CommonAnnotationBeanPostProcessor + +[CommonAnnotationBeanPostProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java) +的主要功能是处理通用 java 注解`javax.annotation.*` + +```java +public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor + implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable { + // 处理属性注入 + @Override + public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { + // 查找需要注入的元信息 + InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs); + try { + // 注入 + metadata.inject(bean, beanName, pvs); + } + catch (Throwable ex) { + // ... 代码省略 + } + return pvs; + } + + // 查找需要注入的元信息 + private InjectionMetadata findResourceMetadata(String beanName, final Class clazz, @Nullable PropertyValues pvs) { + // 加锁的方式取出 + InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); + if (InjectionMetadata.needsRefresh(metadata, clazz)) { + synchronized (this.injectionMetadataCache) { + metadata = this.injectionMetadataCache.get(cacheKey); + if (InjectionMetadata.needsRefresh(metadata, clazz)) { + if (metadata != null) { + metadata.clear(pvs); + } + // 构建元信息 + metadata = buildResourceMetadata(clazz); + this.injectionMetadataCache.put(cacheKey, metadata); + } + } + } + return metadata; + } +} +``` + +```java +public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor + implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable { + // 构建元信息 + private InjectionMetadata buildResourceMetadata(final Class clazz) { + // ... 代码省略 + + // 注入元素集合 + List elements = new ArrayList<>(); + Class targetClass = clazz; + + do { + // 当前元素集合 + final List currElements = new ArrayList<>(); + // 遍历本地属性 + ReflectionUtils.doWithLocalFields(targetClass, field -> { + // @WebServiceRef 注解 + if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) { + if (Modifier.isStatic(field.getModifiers())) { + // 静态属性不能注入 + } + currElements.add(new WebServiceRefElement(field, field, null)); + } + // @EJB 注解 + else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) { + if (Modifier.isStatic(field.getModifiers())) { + // 静态属性不能注入 + } + currElements.add(new EjbRefElement(field, field, null)); + } + // @Resource 注解 + else if (field.isAnnotationPresent(Resource.class)) { + if (Modifier.isStatic(field.getModifiers())) { + // 静态属性不能注入 + } + if (!this.ignoredResourceTypes.contains(field.getType().getName())) { + currElements.add(new ResourceElement(field, field, null)); + } + } + }); + + // 遍历本地方法 + ReflectionUtils.doWithLocalMethods(targetClass, method -> { + Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); + + // ... 代码省略 + + // @WebServiceRef 注解 + if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) { + if (Modifier.isStatic(method.getModifiers())) { + // 静态方法不能注入 + } + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); + currElements.add(new WebServiceRefElement(method, bridgedMethod, pd)); + } + // @EJB 注解 + else if (ejbClass != null && bridgedMethod.isAnnotationPresent(ejbClass)) { + if (Modifier.isStatic(method.getModifiers())) { + // 静态方法不能注入 + } + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); + currElements.add(new EjbRefElement(method, bridgedMethod, pd)); + } + // @Resource 注解 + else if (bridgedMethod.isAnnotationPresent(Resource.class)) { + if (Modifier.isStatic(method.getModifiers())) { + // 静态方法不能注入 + } + if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) { + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); + currElements.add(new ResourceElement(method, bridgedMethod, pd)); + } + } + }); + + // 添加进注入元素集合 + elements.addAll(0, currElements); + // 遍历父类 + targetClass = targetClass.getSuperclass(); + } + while (targetClass != null && targetClass != Object.class); + + return InjectionMetadata.forElements(elements, clazz); + } +} +``` + +## 4. PersistenceAnnotationBeanPostProcessor + +[PersistenceAnnotationBeanPostProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java) +的主要功能是处理持久化 java 注解`javax.persistence.*` + +```java +public class PersistenceAnnotationBeanPostProcessor + implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor, + MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable { + // 处理属性注入 + @Override + public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { + // 查找需要注入的元信息 + InjectionMetadata metadata = findPersistenceMetadata(beanName, bean.getClass(), pvs); + try { + // 注入 + metadata.inject(bean, beanName, pvs); + } + catch (Throwable ex) { + // ... 代码省略 + } + return pvs; + } + + // 查找需要注入的元信息 + private InjectionMetadata findPersistenceMetadata(String beanName, final Class clazz, @Nullable PropertyValues pvs) { + // 加锁的方式取出 + InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); + if (InjectionMetadata.needsRefresh(metadata, clazz)) { + synchronized (this.injectionMetadataCache) { + metadata = this.injectionMetadataCache.get(cacheKey); + if (InjectionMetadata.needsRefresh(metadata, clazz)) { + if (metadata != null) { + metadata.clear(pvs); + } + // 构建元信息 + this.injectionMetadataCache.put(cacheKey, metadata); + } + } + } + return metadata; + } +} +``` + +```java +public class PersistenceAnnotationBeanPostProcessor + implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor, + MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable { + // 构建元信息 + private InjectionMetadata buildPersistenceMetadata(final Class clazz) { + // ... 代码省略 + + // 注入元素集合 + List elements = new ArrayList<>(); + Class targetClass = clazz; + + do { + // 当前元素集合 + final List currElements = new ArrayList<>(); + // 遍历本地属性 + ReflectionUtils.doWithLocalFields(targetClass, field -> { + // 有 @PersistenceContext、@PersistenceUnit 注解 + if (field.isAnnotationPresent(PersistenceContext.class) || + field.isAnnotationPresent(PersistenceUnit.class)) { + if (Modifier.isStatic(field.getModifiers())) { + // 静态属性不能注入 + } + currElements.add(new PersistenceElement(field, field, null)); + } + }); + + // 遍历本地方法 + ReflectionUtils.doWithLocalMethods(targetClass, method -> { + Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); + + // ... 代码省略 + + // 有 @PersistenceContext、@PersistenceUnit 注解 + if ((bridgedMethod.isAnnotationPresent(PersistenceContext.class) || + bridgedMethod.isAnnotationPresent(PersistenceUnit.class)) && + method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { + if (Modifier.isStatic(method.getModifiers())) { + // 静态方法不能注入 + } + PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); + currElements.add(new PersistenceElement(method, bridgedMethod, pd)); + } + }); + + // 添加进注入元素集合 + elements.addAll(0, currElements); + // 遍历父类 + targetClass = targetClass.getSuperclass(); + } + while (targetClass != null && targetClass != Object.class); + + return InjectionMetadata.forElements(elements, clazz); + } +} +``` + +## 5. EventListenerMethodProcessor + +[EventListenerMethodProcessor](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java) +的主要功能是处理事件监听`@EventListener` + +```java +public class EventListenerMethodProcessor + implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor { + // 单例bean初始化后 + @Override + public void afterSingletonsInstantiated() { + ConfigurableListableBeanFactory beanFactory = this.beanFactory; + + // 获取所有的bean + String[] beanNames = beanFactory.getBeanNamesForType(Object.class); + for (String beanName : beanNames) { + Class type = null; + try { + // 获取bean类型 + type = AutoProxyUtils.determineTargetClass(beanFactory, beanName); + } + catch (Throwable ex) { + // ... 代码省略 + } + if (type != null) { + // ... 代码省略 + + try { + // 处理 bean + processBean(beanName, type); + } + catch (Throwable ex) { + // ... 代码省略 + } + } + } + } + + // 处理 bean + private void processBean(final String beanName, final Class targetType) { + // 是以 org.springframework. 开头的类或有 @EventListener 注解 + if (!this.nonAnnotatedClasses.contains(targetType) && + AnnotationUtils.isCandidateClass(targetType, EventListener.class) && + !isSpringContainerClass(targetType)) { + + Map annotatedMethods = null; + try { + // 选择有 @EventListener 注解的方法 + annotatedMethods = MethodIntrospector.selectMethods(targetType, + (MethodIntrospector.MetadataLookup) method -> + AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class)); + } + catch (Throwable ex) { + // ... 代码省略 + } + + // 上下文对象 + ConfigurableApplicationContext context = this.applicationContext; + // 监听器工厂 + List factories = this.eventListenerFactories; + + // 遍历方法 + for (Method method : annotatedMethods.keySet()) { + // 遍历工厂 + for (EventListenerFactory factory : factories) { + // 如果工厂直接解析监听方法 + if (factory.supportsMethod(method)) { + // 包装方法 + Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName)); + // 封装为标准的监听器 + ApplicationListener applicationListener = + factory.createApplicationListener(beanName, targetType, methodToUse); + + // ... 代码省略 + + // 添加进上下文 + context.addApplicationListener(applicationListener); + break; + } + } + } + } + } +} +``` + +## 6. DefaultEventListenerFactory + +[DefaultEventListenerFactory](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/event/DefaultEventListenerFactory.java) +的主要功能是封装有`@EventListener`注解的方法为标准的监听器 + +```java +public class DefaultEventListenerFactory implements EventListenerFactory, Ordered { + @Override + public ApplicationListener createApplicationListener(String beanName, Class type, Method method) { + return new ApplicationListenerMethodAdapter(beanName, type, method); + } +} +``` + +本质上就是用 [ApplicationListenerMethodAdapter](https://github.com/spring-projects/spring-framework/blob/v5.3.10/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java) + +```java +public class ApplicationListenerMethodAdapter implements GenericApplicationListener { + // 调用监听方法 + @Override + public void onApplicationEvent(ApplicationEvent event) { + processEvent(event); + } + + // 处理事件 + public void processEvent(ApplicationEvent event) { + // 获取调用方法的参数,如果有payload,获取payload,没有就是event本身 + Object[] args = resolveArguments(event); + // 如果符合@EventListener的condition设置,则触发 + if (shouldHandle(event, args)) { + // 调用method.invoke获取结果 + Object result = doInvoke(args); + if (result != null) { + // 以此结果,继续派发其他事件 + handleResult(result); + } + } + } +} +``` + +## 后续 + +更多博客,查看 [https://github.com/senntyou/blogs](https://github.com/senntyou/blogs) + +作者:[深予之 (@senntyou)](https://github.com/senntyou) + +版权声明:自由转载-非商用-非衍生-保持署名([创意共享 3.0 许可证](https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh))