Spring Framework 源码赏析
Table of Contents
- 1. Spring 核心类和方法
- 2. 容器实现原理
- 3. Bean 实现原理
- 4. 容器功能扩展
- 5. AOP 面向切面编程
- 6. SpringBoot 自动装配
- 7. 参考链接
1 Spring 核心类和方法
1.1 核心类
- BeanFactory
Bean工厂
getBean(...)
- AbstractBeanFactory (实现了 BeanFactory 的核心方法)
doGetBean(...)
- DefaultListableBeanFactory
- BeanDefinition
Bean定义
- BeanDefinition 描述 Bean 实例定义的相关信息
- BeanDefinition 提供 BeanFactoryPostProcessor 操作属性的最小接口
- 抽象类
AbstractBeanDefinition
实现了一些常用的方法setBeanClassName(...)
isSingleton(...)
- BeanDefinitionReader 接口提供
loadBeanDefinitions(...)
方法- 读取 BeanDefinition 对象
- 在
XmlBeanDefinitionReader
具体实现doLoadBeanDefinitions(...)
读取 XML 中定义的 Bean 数据
- SingletonBeanRegistry
单例 Bean 注册
registerSingleton(...)
方法提供注册单例 Bean 入口- 常见的实现类
DefaultSingletonBeanRegistry
registerBeanDefinition(...)
注册 BeanDefinitionMap<String, BeanDefinition> beanDefinitionMap
registerBeanDefinition(...)
添加 BeanDefinition 到 beanDefinitionMap
- 三级缓存解决循环依赖
Map<String, Object> singletonObjects
Map<String, Object> earlySingletonObjects
Map<String, ObjectFactory<?>> singletonFactories
- ApplicationContext
应用上下文
- AbstractApplicationContext
refresh()
实现 Spring Bean 加载的核心逻辑- 包含 15 个子函数处理 Bean 全生命周期的事情
ClassPathXmlApplicationContext
读取 XML 文件中的 BeanDefinitionAnnotationConfigApplicationContext
扫描包含@Component
注解的 BeanDefinition
- AbstractApplicationContext
- BeanFactoryPostProcessor
Bean工厂后置处理器
- 函数式接口
@FunctionalInterface
- 提供注册 Registration
- 处理加载顺序 Ordering
postProcessBeanFactory(...)
beanFactory 初始化过后调用- 常见子接口
BeanDefinitionRegistryPostProcessor
- 提交 SPI 机制,提供 BeanDefinition 注册机制
postProcessBeanDefinitionRegistry(...)
注册器后置处理器
- 函数式接口
- BeanPostProcessor
Bean后置处理器
- 提供自定义 Bean 实例化的处理接口扩展
postProcessBeforeInitialization(Object bean, String beanName)
- Bean 实例化前置处理方法
postProcessAfterInitialization(Object bean, String beanName)
- Bean 实例化后置处理方法
- 常见子接口
InstantiationAwareBeanPostProcessor
postProcessBeforeInstantiation(...)
postProcessAfterInitialization(...)
postProcessAfterInstantiation(...)
postProcessBeforeInitialization(...)
SmartInstantiationAwareBeanPostProcessor
- 继承自
InstantiationAwareBeanPostProcessor
determineCandidateConstructors(...)
predictBeanType(...)
getEarlyBeanReference(...)
- 继承自
DestructionAwareBeanPostProcessor
postProcessBeforeDestruction(...)
requiresDestruction(...)
MergedBeanDefinitionPostProcessor
postProcessMergedBeanDefinition(...)
resetBeanDefinition(...)
1.2 IoC 的理解
IoC 叫做控制反转 (Inversion of Control)
- 通过 Spring 来管理 Bean 的创建、配置和生命周期,相当于把控制权交给了框架
- 这样做的好处就是解耦,不需要人工来管理对象之间复杂的依赖关系
- 在 Spring 里面,主要提供了 BeanFactory 和 ApplicationContext 两种 IoC 容器, 通过他们来实现对 Bean 的管理
1.3 IoC 核心方法
getBean()
获取 BeandoGetBean()
真正获取 BeantransformedBeanName()
转换 Bean 名称getSingleton()
获取单例 BeangetParentBeanFactory()
获取父 Bean 工厂getDependsOn()
获取依赖项getSingleton()
获取单例 BeancreateBean()
创建 BeanresolveBeforeInstantiation()
实例化前解析doCreateBean()
真正创建 BeancreateBeanInstance()
创建 Bean 实例addSingletonFactory()
添加单例工厂populateBean()
填充 Bean 属性initializeBean()
初始化 BeanaddSingleton()
添加单例 Bean
添加单例的典型调用栈
addSingleton:134, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) registerSingleton:123, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) registerSingleton:1061, DefaultListableBeanFactory (org.springframework.beans.factory.support) prepareBeanFactory:680, AbstractApplicationContext (org.springframework.context.support) refresh:525, AbstractApplicationContext (org.springframework.context.support) <init>:101, AnnotationConfigApplicationContext (org.springframework.context.annotation) main:29, MyApp02 (io.github.jeanhwea.app02_bean_lifecycle)
添加单例工厂的典型调用栈
addSingletonFactory:152, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doCreateBean:588, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1519736165 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$36) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:207, AbstractBeanFactory (org.springframework.beans.factory.support) invokeBeanFactoryPostProcessors:89, PostProcessorRegistrationDelegate (org.springframework.context.support) invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support) refresh:532, AbstractApplicationContext (org.springframework.context.support) <init>:101, AnnotationConfigApplicationContext (org.springframework.context.annotation) main:29, MyApp02 (io.github.jeanhwea.app02_bean_lifecycle)
填充 Bean 的典型调用栈
populateBean:1370, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:594, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1519736165 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$36) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:207, AbstractBeanFactory (org.springframework.beans.factory.support) invokeBeanFactoryPostProcessors:89, PostProcessorRegistrationDelegate (org.springframework.context.support) invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support) refresh:532, AbstractApplicationContext (org.springframework.context.support) <init>:101, AnnotationConfigApplicationContext (org.springframework.context.annotation) main:29, MyApp02 (io.github.jeanhwea.app02_bean_lifecycle)
2 容器实现原理
2.1 Bean 工厂接口: BeanFactory
BeanFactory
是 Spring 的 Bean 工厂的接口定义,它定义对 Spring Bean 容器访问的
基本操作方法,这里简化如下
public interface BeanFactory { // FactoryBean 的 beanName 前缀 String FACTORY_BEAN_PREFIX = "&"; // 获取 Bean 的主方法 Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType); <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType); boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; @Nullable Class<?> getType(String name) throws NoSuchBeanDefinitionException; @Nullable Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException; String[] getAliases(String name); }
2.2 Bean 工厂的实现类: DefaultListableBeanFactory
DefaultListableBeanFactory
是实现 BeanFactory
接口的核心类,熟悉它的类继
承和实现接口是了解 Bean 工厂功能的基本方法, DefaultListableBeanFactory
的
关系如下
org.springframework.beans.factory.support Class DefaultListableBeanFactory java.lang.Object org.springframework.core.SimpleAliasRegistry org.springframework.beans.factory.support.DefaultSingletonBeanRegistry org.springframework.beans.factory.support.FactoryBeanRegistrySupport org.springframework.beans.factory.support.AbstractBeanFactory org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory org.springframework.beans.factory.support.DefaultListableBeanFactory All Implemented Interfaces: Serializable, BeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory, ConfigurableListableBeanFactory, SingletonBeanRegistry, HierarchicalBeanFactory, ListableBeanFactory, BeanDefinitionRegistry, org.springframework.core.AliasRegistry Direct Known Subclasses: XmlBeanFactory
这里说明一下重要的类和接口的作用
SimpleAliasRegistry
实现了AliasRegistry
接口AliasRegistry
定义了对别名的增删查改操作
DefaultSingletonBeanRegistry
实现了SingletonBeanRegistry
接口SingletonBeanRegistry
定义了对单例 Bean 的注册及获取方法SingletonBeanRegistry
通过三级缓存来解决循环依赖
FactoryBeanRegistrySupport
实现了对FactoryBean
的操作支持- 在 Spring 管理中,
FactoryBean
的 beanName 以&
开头 FactoryBean
的创建方式和普通 Spring Bean 是不一样的,它没有 BeanDefinition, 直接通过实现T getObject()
方法来返回创建的 Bean 对象FactoryBean
还需要实现一些其他的方法,例如:isSingleton()
,getObjectType()
- 在 Spring 管理中,
AbstractBeanFactory
实现了BeanFactory
接口BeanFactory
接口的直接实现是AbstractBeanFactory
抽象类AbstractBeanFactory
有很多核心方法doGetBean(...)
实现了获取 Bean 的核心逻辑isSingleton(...)
实现了判断 Bean 是否单例的核心逻辑isPrototype(...)
实现了判断 Bean 是否原型的核心逻辑
HierarchicalBeanFactory
接口继承自BeanFactory
, 它增强了对 parentFactory 的支持ConfigurableBeanFactory
接口提供了配置 Factory 的各种操作setBeanClassLoader(...)
设置 Bean 的类加载器registerDependentBean(...)
方法注册依赖 BeanregisterScope(...)
注册 ScopeisFactoryBean(...)
判断是否为 FactoryBeandestroyBean(...)
销毁 Bean
ListableBeanFactory
定义了一些获取 Bean 清单的操作getBeanDefinitionCount()
获取工厂中定义 BeanDefinition 的数量getBeanDefinitionNames()
获取工厂定义的 BeanDefinition 名称
2.3 Bean 定义的读取器: XmlBeanDefinitionReader
XmlBeanDefinitionReader
是实现读取 BeanDefinition 的类,它的继承关系如下
org.springframework.beans.factory.xml Class XmlBeanDefinitionReader java.lang.Object org.springframework.beans.factory.support.AbstractBeanDefinitionReader org.springframework.beans.factory.xml.XmlBeanDefinitionReader All Implemented Interfaces: BeanDefinitionReader, org.springframework.core.env.EnvironmentCapable
这里说明一下重要的类和接口的作用
AbstractBeanDefinitionReader
实现了对 BeanDefinition 的读取操作,它包含 如下成员变量private final BeanDefinitionRegistry registry; private ResourceLoader resourceLoader; private ClassLoader beanClassLoader; private Environment environment; private BeanNameGenerator beanNameGenerator = DefaultBeanNameGenerator.INSTANCE;
- registry 表示 BeanDefinition 的注册类
- resourceLoader 实现了资源加载
- environment 实现了读取系统环境变量和 Java 属性
- beanNameGenerator 是 beanName 生成器
XmlBeanDefinitionReader
直接继承自AbstractBeanDefinitionReader
, 增加了DocumentLoader
将资源转化成 Document 对象功能- 添加了对 XML 的格式验证的方法
- DTD (Document Type Definition) 验证
- XSD (XML Schema Definition) 验证
2.4 BeanDefinition 自动加载流程
DefaultListableBeanFactory
类定义了存储 BeanDefinition 类的哈希表, 具体定义如下
/** Map of bean definition objects, keyed by bean name. */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); /** Map of singleton and non-singleton bean names, keyed by dependency type. */ private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64); /** Map of singleton-only bean names, keyed by dependency type. */ private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64); /** List of bean definition names, in registration order. */ private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
最终 BeanDefinition 通过调用 registerBeanDefinition(...)
方法注册到
beanDefinitionMap
中,代码的注释也写了是对 BeanDefinitionRegistry
的实现
//--------------------------------------------------------------------- // Implementation of BeanDefinitionRegistry interface //--------------------------------------------------------------------- @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
在 registerBeanDefinition(...)
方法中添加端点可以获得如下的调用栈
registerBeanDefinition:914, DefaultListableBeanFactory (org.springframework.beans.factory.support) registerBeanDefinition:164, BeanDefinitionReaderUtils (org.springframework.beans.factory.support) processBeanDefinition:311, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml) parseDefaultElement:197, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml) parseBeanDefinitions:176, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml) doRegisterBeanDefinitions:149, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml) registerBeanDefinitions:96, DefaultBeanDefinitionDocumentReader (org.springframework.beans.factory.xml) registerBeanDefinitions:509, XmlBeanDefinitionReader (org.springframework.beans.factory.xml) doLoadBeanDefinitions:389, XmlBeanDefinitionReader (org.springframework.beans.factory.xml) loadBeanDefinitions:336, XmlBeanDefinitionReader (org.springframework.beans.factory.xml) loadBeanDefinitions:305, XmlBeanDefinitionReader (org.springframework.beans.factory.xml) loadBeanDefinitions:188, AbstractBeanDefinitionReader (org.springframework.beans.factory.support) loadBeanDefinitions:224, AbstractBeanDefinitionReader (org.springframework.beans.factory.support) loadBeanDefinitions:195, AbstractBeanDefinitionReader (org.springframework.beans.factory.support) loadBeanDefinitions:257, AbstractBeanDefinitionReader (org.springframework.beans.factory.support) loadBeanDefinitions:128, AbstractXmlApplicationContext (org.springframework.context.support) loadBeanDefinitions:94, AbstractXmlApplicationContext (org.springframework.context.support) refreshBeanFactory:133, AbstractRefreshableApplicationContext (org.springframework.context.support) obtainFreshBeanFactory:637, AbstractApplicationContext (org.springframework.context.support) refresh:522, AbstractApplicationContext (org.springframework.context.support) <init>:144, ClassPathXmlApplicationContext (org.springframework.context.support) <init>:85, ClassPathXmlApplicationContext (org.springframework.context.support) main:10, MyApp01 (io.github.jeanhwea.app01)
观察调用栈可以得到 BeanDefinition 的加载步骤如下:
- 入口方法为
AbstractApplicationContext#refresh(...)
obtainFreshBeanFactory(...)
方法获取 BeanFactory 的同时需要注册 BeanDefinitionXmlBeanDefinitionReader#doLoadBeanDefinitions(...)
方法完成如下操作定义了 documentLoader 成员变量
private DocumentLoader documentLoader = new DefaultDocumentLoader();
- 首先调用
doLoadDocument(inputSource, resource)
读取到 Document 对象 - 然后调用
registerBeanDefinitions(doc, resource)
完成 BeanDefinition 的 注册
- 调用
parseDefaultElement(...)
方法对默认元素进行解析- 对 import 类型标签解析
- 对 alias 类型标签解析
- 对 bean 类型标签解析
- 对嵌套 bean 类型标签解析
- 接着对标签进行处理,最终交付到
DefaultListableBeanFactory#registerBeanDefinition(...)
方法进行注册
2.5 BeanDefinition 注册的实现
DefaultListableBeanFactory
的 registerBeanDefinition(...)
才是真正实现注
册 BeanDefinition 逻辑,其代码如下:
- 对 beanDefinition 进行验证
- 检查 beanDefinition 是否存在
- 如果存在,判断是否覆盖对应的 BeanDefinition
- 如果 beanDefinition 不存在,进行创建并注册
//--------------------------------------------------------------------- // Implementation of BeanDefinitionRegistry interface //--------------------------------------------------------------------- @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
在上面注册过程中, hasBeanCreationStarted()
方法用于判断 Bean 是否开始创建,
它实现逻辑在父类 AbstractBeanFactory
中
/** * Check whether this factory's bean creation phase already started, * i.e. whether any bean has been marked as created in the meantime. * @since 4.2.2 * @see #markBeanAsCreated */ protected boolean hasBeanCreationStarted() { return !this.alreadyCreated.isEmpty(); }
父类 AbstractBeanFactory
中定义了一个集合记录正在创建的 Bean
/** Names of beans that have already been created at least once. */ private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
创建时通过 markBeanAsCreated(...)
方法标记,注意对 alreadyCreated
的访问
是需要加锁的
/** * Mark the specified bean as already created (or about to be created). * <p>This allows the bean factory to optimize its caching for repeated * creation of the specified bean. * @param beanName the name of the bean */ protected void markBeanAsCreated(String beanName) { if (!this.alreadyCreated.contains(beanName)) { synchronized (this.mergedBeanDefinitions) { if (!this.alreadyCreated.contains(beanName)) { // Let the bean definition get re-merged now that we're actually creating // the bean... just in case some of its metadata changed in the meantime. clearMergedBeanDefinition(beanName); this.alreadyCreated.add(beanName); } } } }
2.6 BeanDefinition 移除的实现
BeanDefinition 的移除方法如下,通过 removeBeanDefinition(...)
方法
@Override public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { Assert.hasText(beanName, "'beanName' must not be empty"); BeanDefinition bd = this.beanDefinitionMap.remove(beanName); if (bd == null) { if (logger.isTraceEnabled()) { logger.trace("No bean named '" + beanName + "' found in " + this); } throw new NoSuchBeanDefinitionException(beanName); } if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames); updatedDefinitions.remove(beanName); this.beanDefinitionNames = updatedDefinitions; } } else { // Still in startup registration phase this.beanDefinitionNames.remove(beanName); } this.frozenBeanDefinitionNames = null; resetBeanDefinition(beanName); }
移除 BeanDefinition 中调用了刷新 BeanDefinition 的方法
resetBeanDefinition(...)
/** * Reset all bean definition caches for the given bean, * including the caches of beans that are derived from it. * <p>Called after an existing bean definition has been replaced or removed, * triggering {@link #clearMergedBeanDefinition}, {@link #destroySingleton} * and {@link MergedBeanDefinitionPostProcessor#resetBeanDefinition} on the * given bean and on all bean definitions that have the given bean as parent. * @param beanName the name of the bean to reset * @see #registerBeanDefinition * @see #removeBeanDefinition */ protected void resetBeanDefinition(String beanName) { // Remove the merged bean definition for the given bean, if already created. clearMergedBeanDefinition(beanName); // Remove corresponding bean from singleton cache, if any. Shouldn't usually // be necessary, rather just meant for overriding a context's default beans // (e.g. the default StaticMessageSource in a StaticApplicationContext). destroySingleton(beanName); // Notify all post-processors that the specified bean definition has been reset. for (BeanPostProcessor processor : getBeanPostProcessors()) { if (processor instanceof MergedBeanDefinitionPostProcessor) { ((MergedBeanDefinitionPostProcessor) processor).resetBeanDefinition(beanName); } } // Reset all bean definitions that have the given bean as parent (recursively). for (String bdName : this.beanDefinitionNames) { if (!beanName.equals(bdName)) { BeanDefinition bd = this.beanDefinitionMap.get(bdName); // Ensure bd is non-null due to potential concurrent modification // of the beanDefinitionMap. if (bd != null && beanName.equals(bd.getParentName())) { resetBeanDefinition(bdName); } } } }
2.7 BeanDefinition 获取的实现
DefaultListableBeanFactory
的实现获取 BeanDefinition 的逻辑如下
@Override public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { BeanDefinition bd = this.beanDefinitionMap.get(beanName); if (bd == null) { if (logger.isTraceEnabled()) { logger.trace("No bean named '" + beanName + "' found in " + this); } throw new NoSuchBeanDefinitionException(beanName); } return bd; }
2.8 <bean/>
标签解析
之前在 BeanDefinition 自动加载流程中忽略了对 <bean/>
标签的解析,其核心实现
逻辑 BeanDefinitionDocumentReader
类中的 processBeanDefinition(...)
方法
/** * Process the given bean element, parsing the bean definition * and registering it with the registry. */ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
可以看出对 XML 标签的解析核心逻辑为 parseBeanDefinitionElement(...)
/** * Parses the supplied {@code <bean>} element. May return {@code null} * if there were errors during parse. Errors are reported to the * {@link org.springframework.beans.factory.parsing.ProblemReporter}. */ @Nullable public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) { String id = ele.getAttribute(ID_ATTRIBUTE); String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); List<String> aliases = new ArrayList<>(); if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isTraceEnabled()) { logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { beanName = this.readerContext.generateBeanName(beanDefinition); // Register an alias for the plain bean class name, if still possible, // if the generator returned the class name plus a suffix. // This is expected for Spring 1.2/2.0 backwards compatibility. String beanClassName = beanDefinition.getBeanClassName(); if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); } } if (logger.isTraceEnabled()) { logger.trace("Neither XML 'id' nor 'name' specified - " + "using generated bean name [" + beanName + "]"); } } catch (Exception ex) { error(ex.getMessage(), ele); return null; } } String[] aliasesArray = StringUtils.toStringArray(aliases); return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; }
3 Bean 实现原理
3.1 Bean 的生命周期
SpringBean 生命周期简单概括为 4 个阶段:
- 实例化: 创建一个 Bean 对象
- 填充属性: 为属性赋值
- 初始化: 包括如下的基本逻辑
- 如果实现了 xxxAware 接口, 通过不同类型的 Aware 接口拿到 Spring 容器的资源
- 如果实现了 BeanPostProcessor 接口,则会回调该接口的
- postProcessBeforeInitialzation 方法
- postProcessAfterInitialization 方法
- 如果配置了 init-method 方法,则会执行 init-method 配置的方法
- 销毁: 容器关闭后,如果 Bean 实现了 DisposableBean 接口, 则会回调该接口 的 destroy 方法如果配置了 destroy-method 方法,则会执行 destroy-method 配 置的方法
BeanFactory
的注释中完整地说明的实现标准 BeanFactory 的代码
- BeanFactory 初始化过程,支持的标准 Bean 的生命周期
BeanNameAware#setBeanName(...)
BeanClassLoaderAware#setBeanClassLoader(...)
BeanFactoryAware#setBeanFactory(...)
EnvironmentAware#setEnvironment(...)
EmbeddedValueResolverAware#setEmbeddedValueResolver(...)
ResourceLoaderAware#setResourceLoader(...)
在 ApplicationContext 中ApplicationEventPublisherAware#setApplicationEventPublisher(...)
在 ApplicationContext 中MessageSourceAware#setMessageSource(...)
在 ApplicationContext 中ApplicationContextAware#setApplicationContext(...)
在 ApplicationContext 中ServletContextAware#setServletContext(...)
在 ApplicationContext 中BeanPostProcessors
的一系列postProcessBeforeInitialization(...)
方法InitializingBean#afterPropertiesSet(...)
- a custom init-method definition
BeanPostProcessors
的一系列postProcessAfterInitialization(...)
方法
- 关闭 BeanFactory 时,执行的 Bean 销毁方法
DestructionAwareBeanPostProcessors
的一系列postProcessBeforeDestruction(...)
方法DisposableBean#destroy(...)
- a custom destroy-method definition
3.2 Bean 的流程分析
实例化 Bean 的方法为 BeanUtils#instantiateClass(...)
, 先添加断点获取调用栈
instantiateClass:185, BeanUtils (org.springframework.beans) instantiate:87, SimpleInstantiationStrategy (org.springframework.beans.factory.support) instantiateBean:1312, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBeanInstance:1214, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:557, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1027007693 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$29) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:207, AbstractBeanFactory (org.springframework.beans.factory.support) invokeBeanFactoryPostProcessors:89, PostProcessorRegistrationDelegate (org.springframework.context.support) invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support) refresh:532, AbstractApplicationContext (org.springframework.context.support) main:18, MyApp02 (io.github.jeanhwea.app02)
先分析调用栈,可以知道创建 Bean 的入口是 refresh()
方法的
invokeBeanFactoryPostProcessors()
方法,这里牵扯到几个核心的方法
AbstractApplicationContext#refresh()
AbstractBeanFactory#doGetBean(...)
AbstractAutowireCapableBeanFactory#instantiateBean(...)
3.2.1 实例化 Bean: instantiateBean()
方法
instantiateBean(...)
实例化 Bean 主要完成如下工作
- 使用 InstantiationStrategy 实例化策略来实例化 Bean, Spring 中创建 Bean 有如
下两种方式
- 通过
BeanUtils.instantiateClass()
方法创建实例 - 通过
new CglibSubclassCreator(bd, owner).instantiate(ctor, args)
方式 进行创建
- 通过
- 添加 BeanWrapper 封装 Bean 对象
- 实现类为
BeanWrapperImpl
BeanWrapperImpl
继承自AbstractNestablePropertyAccessor
AbstractNestablePropertyAccessor#setPropertyValue(...)
方法设置属性值
- 实现类为
/** * Instantiate the given bean using its default constructor. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @return a BeanWrapper for the new instance */ protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, parent), getAccessControlContext()); } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
3.2.2 获取 Bean 实例: doGetBean()
方法
doGetBean(...)
方法是获取 Bean 的最终处理函数,它的逻辑比较复杂,可以分成
以下流程
- 获取 beanName
- 解析带有别名的 Bean 到最终的名称
- 去除 FactoryBean 的修饰符,即
&
前缀
- 缓存获取
- 调用
DefaultSingletonBeanRegistry#getSingleton()
尝试从单例容器缓存中 获取 - 单例 Bean 只创建一次,创建完成直接放入缓存,参考
DefaultSingletonBeanRegistry
的实现 - 依赖的 Bean 避免循环依赖,只记录
ObjectFactory
对象, 参考singletonFactories
变量的定义及循环依赖的解决方法
- 调用
- 创建 Bean 实例
- 获取 FactoryBean 生成的 Bean 实例
- FactoryBean 实例需要获取到的对象是
factory-method
返回的 Bean 对象 getObjectForBeanInstance()
方法实现了从 Bean 实例中获取 Bean 对象的 逻辑,后续再说明该方法的逻辑
- FactoryBean 实例需要获取到的对象是
- 如果不是 FactoryBean
- 调用
isPrototypeCurrentlyInCreation(...)
判断创建原型 Bean 是否出现 循环依赖 - 尝试从 parentBeanFactory 中获取 Bean
- 将 BeanDefinition 进行合并,得到
RootBeanDefinition
, 并检验 - 调用
markBeanAsCreated()
方法标记创建 Bean - 解决 Bean 依赖
- Bean 是动态加载的,当前待创建 Bean 的可能存在依赖项
- 解决依赖的策略是顺序寻找出所有依赖,并完成创建
- 通过不同的 scope 完成对应 Bean 的创建
- 单例 Bean 创建:
getSingleton(...)
- 原型 Bean 创建:
getSingleton(...)
- 其它情况 Bean 创建,例如:
@RequestScope
@SessionScope
等
- 单例 Bean 创建:
- 调用
- 获取 FactoryBean 生成的 Bean 实例
- 检查 Bean 实例,完成类型转换
/** * Return an instance, which may be shared or independent, of the specified bean. * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @param typeCheckOnly whether the instance is obtained for a type check, * not for actual use * @return an instance of the bean * @throws BeansException if the bean could not be created */ @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
3.3 特殊的 Spring Bean: FactoryBean
FactoryBean 不同于普通的 Bean, FactoryBean 自身就是一个组装 Bean 的微型工厂,
即在调用 BeanFactory#getBean(...)
方法时不返回 FactoryBean,而是返回工厂方
法返回的 Bean,定义 FactoryBean 只需要实现 FactoryBean
接口即可
public interface FactoryBean<T> { @Nullable T getObject() throws Exception; @Nullable Class<?> getObjectType(); default boolean isSingleton() { return true; } }
getObject(...)
方法返回 FactoryBean 创建的实例,也称工厂方法getObjectType(...)
方法返回 FactoryBean 创建的实例的类型isSingleton(...)
方法返回 FactoryBean 创建的实例的 Scope
3.4 单例 Bean 工厂的实现
3.4.1 单例 Bean 工厂的三级缓存: DefaultSingletonBeanRegistry
类的缓存
DefaultSingletonBeanRegistry
是对单例 Bean 注册的实现类,它的继承关系如下
org.springframework.beans.factory.support Class DefaultSingletonBeanRegistry java.lang.Object org.springframework.core.SimpleAliasRegistry org.springframework.beans.factory.support.DefaultSingletonBeanRegistry All Implemented Interfaces: SingletonBeanRegistry, org.springframework.core.AliasRegistry
DefaultSingletonBeanRegistry
定义了如下成员变量
/** Cache of singleton objects: bean name to bean instance. */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /** Cache of singleton factories: bean name to ObjectFactory. */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** Cache of early singleton objects: bean name to bean instance. */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); /** Set of registered singletons, containing the bean names in registration order. */ private final Set<String> registeredSingletons = new LinkedHashSet<>(256); /** Names of beans that are currently in creation. */ private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** Names of beans currently excluded from in creation checks. */ private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** List of suppressed Exceptions, available for associating related causes. */ @Nullable private Set<Exception> suppressedExceptions; /** Flag that indicates whether we're currently within destroySingletons. */ private boolean singletonsCurrentlyInDestruction = false; /** Disposable bean instances: bean name to disposable instance. */ private final Map<String, Object> disposableBeans = new LinkedHashMap<>(); /** Map between containing bean names: bean name to Set of bean names that the bean contains. */ private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16); /** Map between dependent bean names: bean name to Set of dependent bean names. */ private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64); /** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */ private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
这里需要注意的是其定义的三级缓存结构
- singletonObjects: 一级缓存单例 Bean 对象,用来保存实例化、初始化都完成的 对象
- earlySingletonObjects: 二级缓存早期创建的单例 Bean 对象,用来保存实例化完
成,但是未初始化完成的对象
- earlySingletonObjects 于 singletonObjects 不同之处是,当一个单例 Bean 还 在创建过程中可以将其依赖的单例 Bean 放入 earlySingletonObjects 哈希表内
- 这样做,即使单例 Bean 在创建过程中,调用
getBean(...)
方法依然可以获 取到所依赖的 Bean 对象 - 另外该方案用来循环检测,避免循环依赖
singletonFactories: 三级缓存单例对象工厂 ObjectFactory,用来保存一个对象 工厂,提供一个匿名内部类,用于创建二级缓存中的对象
- singletonFactories 哈希表的值是
ObjectFactory
接口类型 ObjectFactory
是个函数式接口,用于延迟创建 Bean
@FunctionalInterface public interface ObjectFactory<T> { /** * Return an instance (possibly shared or independent) * of the object managed by this factory. * @return the resulting instance * @throws BeansException in case of creation errors */ T getObject() throws BeansException; }
- singletonFactories 哈希表的值是
3.4.2 为什么必须要三级缓存
- 不可以,主要是为了生成代理对象
- 因为三级缓存中放的是生成具体对象的匿名内部类
- 他可以生成代理对象
- 也可以是普通的实例对象
- 使用三级缓存主要是为了保证不管什么时候使用的都是一个对象
- 假设只有二级缓存的情况
- 往二级缓存中放的显示一个普通的 Bean 对象
- BeanPostProcessor 去生成代理对象之后,覆盖掉二级缓存中的普通 Bean 对象
- 那么多线程环境下可能取到的对象会不一致
3.4.3 获取单例 Bean 方法: getSingleton(...)
方法
getSingleton()
方法是获取 Bean 的核心方法, 它的实现如下
// 获取单例,可以从 earlySingletonObjects 中获取 public Object getSingleton(String beanName) { return getSingleton(beanName, true); } // 获取单例,添加是否可以从 earlySingletonObjects 中获取参数 @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
允许从 earlySingletonObjects 获取单例的 getSingleton(...)
方法逻辑比较清晰
- 先尝试从 singletonObjects 中获取 singletonObject, 如果成功直接返回 singletonObject
- 如果获取失败,则尝试从 earlySingletonObjects 中获取 singletonObject, 如果 成功直接返回 singletonObject
- 如果再次失败,尝试从 singletonFactories 中创建 singletonObject,并返回创
建结果
- 首先通过 beanName, 查找到
ObjectFactory
的值, 即 singletonFactory - 若 singletonFactory 存在,调用
singletonFactory.getObject(...)
方法创 建 singletonObject - 创建成功将 singletonObject, 将 singletonObject 添加到 earlySingletonObjects, 并从 singletonFactories 移除 beanName 对应的值
- 首先通过 beanName, 查找到
// 获取单例,主要针对未创建的 Bean 对象,通过 ObjectFactory 创建对象并返回 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; } }
获取单例 Bean 的总逻辑逻辑如下
- 首先尝试从 singletonObjects 获取 singletonObject, 获取成功直接返回 singletonObject
- 如果 singletonObjects 获取失败,则需要创建 singletonObject
- 先调用
beforeSingletonCreation(...)
前置钩子函数 - 调用
ObjectFactory
的getObject(...)
方法来创建 singletonObject - 然后调用
afterSingletonCreation(...)
后置钩子函数 如果有信创建的 singletonObject, 调用
addSingleton(...)
来处理添加新创 建 singletonObjectprotected 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); } }
addSingleton(...)
将新创建的 singletonObject 放入 singletonObjects, 并从 singletonFactories 和 earlySingletonObjects 中移除 singletonObject 对象- 将 singletonObject 添加到 registeredSingletons 中,完成 Bean 的注册
- 先调用
3.4.4 beanInstance 到 beanOject 过程: getObjectForBeanInstance(...)
方法
beanInstance -> beanOject 是将缓存中的 Bean 实例转化成最终用户所需对象的过程,
- 在
doGetBean(...)
方法中的getObjectForBeanInstance(...)
方法实现 - beanInstance 如果是非 FactoryBean, beanInstance 即为 beanOject, 直接返回 创建好的 Bean 对象
- beanInstance 如果是 FactoryBean, 需要调用工厂方法进行处理,创建 beanOject
- 先调用
getCachedObjectForFactoryBean(...)
从缓存中获取,获取成功直接 返回结果 - 如果未获取成功,调用
getObjectFromFactoryBean(...)
创建 beanOject - 最终通过
doGetObjectFromFactoryBean(...)
完成调用工厂方法并获取 beanObject 逻辑
- 先调用
这里分析一下 doGetObjectFromFactoryBean(...)
的逻辑,先查看一下调用栈
doGetObjectFromFactoryBean:161, FactoryBeanRegistrySupport (org.springframework.beans.factory.support) getObjectFromFactoryBean:101, FactoryBeanRegistrySupport (org.springframework.beans.factory.support) getObjectForBeanInstance:1818, AbstractBeanFactory (org.springframework.beans.factory.support) getObjectForBeanInstance:1266, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doGetBean:260, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:1108, AbstractApplicationContext (org.springframework.context.support) main:25, MyApp04 (io.github.jeanhwea.app04_factory_bean)
doGetObjectFromFactoryBean(...)
方法逻辑如下,可以看出在进行了一些校验工作,
最终调用 factory.getObject()
方法获取 beanObject
/** * Obtain an object to expose from the given FactoryBean. * @param factory the FactoryBean instance * @param beanName the name of the bean * @return the object obtained from the FactoryBean * @throws BeanCreationException if FactoryBean object creation failed * @see org.springframework.beans.factory.FactoryBean#getObject() */ private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { object = factory.getObject(); } } catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); } // Do not accept a null value for a FactoryBean that's not fully // initialized yet: Many FactoryBeans just return null then. if (object == null) { if (isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException( beanName, "FactoryBean which is currently in creation returned null from getObject"); } object = new NullBean(); } return object; }
往上跳一级,查看 FactoryBeanRegistrySupport#getObjectFromFactoryBean(...)
方法
/** * Obtain an object to expose from the given FactoryBean. * @param factory the FactoryBean instance * @param beanName the name of the bean * @param shouldPostProcess whether the bean is subject to post-processing * @return the object obtained from the FactoryBean * @throws BeanCreationException if FactoryBean object creation failed * @see org.springframework.beans.factory.FactoryBean#getObject() */ protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above // (e.g. because of circular reference processing triggered by custom getBean calls) Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } beforeSingletonCreation(beanName); try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { afterSingletonCreation(beanName); } } if (containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }
getObjectFromFactoryBean
实现了获取 FactoryBean 的 beanObject 的业务逻辑
- 如果是非单例 FactoryBean,在最外层的 else 代码,直接创建 beanObject
- 如果是单例 FactoryBean
- 首先获取单例缓存池 singletonObjects 的互斥锁
- 尝试从 factoryBeanObjectCache 缓存中获取创建好的 beanObject, 如果成功 直接返回结果
- 如果缓存获取失败,则需要调用
doGetObjectFromFactoryBean(...)
方法创 建 beanObject,并将创建好的 beanObject 放入 factoryBeanObjectCache 缓 存中
- 在上述两种情况过后都需要调用
postProcessObjectFromFactoryBean(...)
方法postProcessObjectFromFactoryBean(...)
是一个空方法- 这样设计是为子类提供扩展点
3.5 Bean 生命周期的实现
3.5.1 Bean 创建的实现类: AbstractAutowireCapableBeanFactory
先看 AbstractAutowireCapableBeanFactory
的类继承关系
org.springframework.beans.factory.support Class AbstractAutowireCapableBeanFactory java.lang.Object org.springframework.core.SimpleAliasRegistry org.springframework.beans.factory.support.DefaultSingletonBeanRegistry org.springframework.beans.factory.support.FactoryBeanRegistrySupport org.springframework.beans.factory.support.AbstractBeanFactory org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory All Implemented Interfaces: BeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory, SingletonBeanRegistry, HierarchicalBeanFactory, org.springframework.core.AliasRegistry
AbstractAutowireCapableBeanFactory
实现了AutowireCapableBeanFactory
接口AutowireCapableBeanFactory
中有管理 Autowire 功能 Bean 的方法createBean(...)
实例化 BeaninitializeBean(...)
初始化 BeandestroyBean(...)
销毁 Bean- 还有一些 Bean 的
*PostProcessor*
的增强函数
public interface AutowireCapableBeanFactory extends BeanFactory { //------------------------------------------------------------------------- // Typical methods for creating and populating external bean instances //------------------------------------------------------------------------- <T> T createBean(Class<T> beanClass) throws BeansException; void autowireBean(Object existingBean) throws BeansException; Object configureBean(Object existingBean, String beanName) throws BeansException; //------------------------------------------------------------------------- // Specialized methods for fine-grained control over the bean lifecycle //------------------------------------------------------------------------- Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException; void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException; Object initializeBean(Object existingBean, String beanName) throws BeansException; Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException; Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException; void destroyBean(Object existingBean); //------------------------------------------------------------------------- // Delegate methods for resolving injection points //------------------------------------------------------------------------- <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException; Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException; @Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException; @Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException; }
3.5.2 Bean 的实例化: createBean(...)
方法
实际实例化 Bean 是在 doCreateBean(...)
方法中完成的,先准备一下调用栈
doCreateBean:552, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1989335500 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$37) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:207, AbstractBeanFactory (org.springframework.beans.factory.support) invokeBeanFactoryPostProcessors:89, PostProcessorRegistrationDelegate (org.springframework.context.support) invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support) refresh:532, AbstractApplicationContext (org.springframework.context.support) <init>:101, AnnotationConfigApplicationContext (org.springframework.context.annotation) main:21, MyApp04 (io.github.jeanhwea.app04_factory_bean)
createBean(...)
方法实现如下
/** * Central method of this class: creates a bean instance, * populates the bean instance, applies post-processors, etc. * @see #doCreateBean */ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
该方法的流程如下
- 通过 BeanDefinition 和 beanName 解析获取到待创建的类 resolvedClass
- 对 override 属性进行标记及验证
lookup-method
,replace-method
等
- 处理 BeanPostProcessors, 进行一些前置处理工作
resolveBeforeInstantiation(...)
方法完成前置处理工作/** * Apply before-instantiation post-processors, resolving whether there is a * before-instantiation shortcut for the specified bean. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @return the shortcut-determined bean instance, or {@code null} if none */ @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) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
applyBeanPostProcessorsBeforeInstantiation(...)
方法在实例化前调用applyBeanPostProcessorsAfterInitialization(...)
方法在初始化后调用
- 调用
doCreateBean(...)
创建 Bean 实例 beanInstance, 并返回 beanInstance
doCreateBean(...)
方法实现如下
/** * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. * <p>Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
该方法实现流程如下
- 如果是单例 Bean, 首先清理缓存
- 通过
createBeanInstance(...)
方法将 BeanDefinition 转化成 BeanWrapper, BeanWrapper 的作用如下- 如果检测到 Supplier, 使用 Supplier 进行实例化,具体实现见
obtainFromSupplier(...)
方法 - 如果存在工厂方法, 则使用工厂方法进行实例化, 具体实现见
instantiateUsingFactoryMethod(...)
- 如果包含多参数构造器,根据参数类型锁定的构造方法,然后调用进行实例化,具
体实现见
autowireConstructor(...)
方法 - 其它情况使用无参构造器进行实例化, 具体实现见
instantiateBean(...)
方法
- 如果检测到 Supplier, 使用 Supplier 进行实例化,具体实现见
- 允许后置处理器合并 BeanDefinition
- 解决依赖,若有依赖项调用
addSingletonFactory(...)
添加到 singletonFactories 缓存中 - 调用
populateBean(...)
方法进行属性填充 - 调用
initializeBean(...)
方法进行初始化 - 循环依赖检测
- 只检测单例 Bean 的循环依赖
- 原型 Bean 的循环检测很难做到,Spring 做法是直接抛出异常
- 注册 DisposableBean
- 便于 destroy-method 在 Bean 销毁时调用
- 完成创建并返回
3.5.3 Bean 的初始化: initializeBean(...)
方法
/** * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * <p>Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @return the initialized bean instance (potentially wrapped) * @see BeanNameAware * @see BeanClassLoaderAware * @see BeanFactoryAware * @see #applyBeanPostProcessorsBeforeInitialization * @see #invokeInitMethods * @see #applyBeanPostProcessorsAfterInitialization */ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
该方法用于初始化 Bean,它完成了如下工作
- 调用 Aware 方法,例如
- BeanFactoryAware
- ApplicationContextAware
- ResourceLoaderAware
- ServletContextAware
- 提供 BeanPostProcessor 的扩展点,环绕调用了如下两个钩子方法
applyBeanPostProcessorsBeforeInitialization(...)
applyBeanPostProcessorsAfterInitialization(...)
- 调用自定义的初始化方法,及 init-method
invokeInitMethods(beanName, wrappedBean, mbd);
3.5.4 Bean 的销毁
在 doCreateBean(...)
方法中调用了 registerDisposableBeanIfNecessary(...)
方法来提供 destroy-method
销毁的扩展
/** * Add the given bean to the list of disposable beans in this factory, * registering its DisposableBean interface and/or the given destroy method * to be called on factory shutdown (if applicable). Only applies to singletons. * @param beanName the name of the bean * @param bean the bean instance * @param mbd the bean definition for the bean * @see RootBeanDefinition#isSingleton * @see RootBeanDefinition#getDependsOn * @see #registerDisposableBean * @see #registerDependentBean */ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
4 容器功能扩展
4.1 应用上下文: ApplicationContext
首先查看 ApplicationContext
接口的相关信息
org.springframework.context Interface ApplicationContext All Superinterfaces: ApplicationEventPublisher, org.springframework.beans.factory.BeanFactory, org.springframework.core.env.EnvironmentCapable, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.beans.factory.ListableBeanFactory, MessageSource, org.springframework.core.io.ResourceLoader, org.springframework.core.io.support.ResourcePatternResolver
可以看出 ApplicationContext
提供了所以 BeanFactory
的功能,另外还扩展了如
下功能
ResourceLoader
加载资源文件ApplicationEventPublisher
事件发布和监听器注册MessageSource
国际化的消息支持HierarchicalBeanFactory
继承父的上下文功能EnvironmentCapable
系统环境变量和 Java 属性支持
4.2 ApplicationContext 接口的常见实现类
4.2.1 ClassPathXmlApplicationContext
读取 ClassPath 中 XML 配置文件的 Bean 定义的容器
org.springframework.context.support Class ClassPathXmlApplicationContext java.lang.Object org.springframework.core.io.DefaultResourceLoader org.springframework.context.support.AbstractApplicationContext org.springframework.context.support.AbstractRefreshableApplicationContext org.springframework.context.support.AbstractRefreshableConfigApplicationContext org.springframework.context.support.AbstractXmlApplicationContext org.springframework.context.support.ClassPathXmlApplicationContext All Implemented Interfaces: Closeable, AutoCloseable, org.springframework.beans.factory.Aware, org.springframework.beans.factory.BeanFactory, org.springframework.beans.factory.BeanNameAware, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.beans.factory.InitializingBean, org.springframework.beans.factory.ListableBeanFactory, ApplicationContext, ApplicationEventPublisher, ConfigurableApplicationContext, Lifecycle, MessageSource, org.springframework.core.env.EnvironmentCapable, org.springframework.core.io.ResourceLoader, org.springframework.core.io.support.ResourcePatternResolver
ClassPathXmlApplicationContext
的构造器的实现如下,该构造器实现逻辑比较清
晰,需要注意的是这里后面调用了刷新上下文的 refresh()
方法
/** * Create a new ClassPathXmlApplicationContext with the given parent, * loading the definitions from the given XML files. * @param configLocations array of resource locations * @param refresh whether to automatically refresh the context, * loading all bean definitions and creating all singletons. * Alternatively, call refresh manually after further configuring the context. * @param parent the parent context * @throws BeansException if context creation failed * @see #refresh() */ public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
4.2.2 AnnotationConfigApplicationContext
读取注解类型 Bean 定义的容器, @Component
, @Service
等
org.springframework.context.annotation Class AnnotationConfigApplicationContext java.lang.Object org.springframework.core.io.DefaultResourceLoader org.springframework.context.support.AbstractApplicationContext org.springframework.context.support.GenericApplicationContext org.springframework.context.annotation.AnnotationConfigApplicationContext All Implemented Interfaces: Closeable, AutoCloseable, org.springframework.beans.factory.BeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.support.BeanDefinitionRegistry, AnnotationConfigRegistry, ApplicationContext, ApplicationEventPublisher, ConfigurableApplicationContext, Lifecycle, MessageSource, org.springframework.core.AliasRegistry, org.springframework.core.env.EnvironmentCapable, org.springframework.core.io.ResourceLoader, org.springframework.core.io.support.ResourcePatternResolver
常见的类简单可以分成以下几类
- 资源处理
Resource
Spring 中关于资源的定义ResourceLoader
提供资源加载方法BeanDefinitionReader
读取接口主要用来读取信息
- 注册形式,在 Spring 中关于注册的几个核心
AliasRegistry
别名注册BeanDefinitionRegistry
Bean 定义注册SingletonBeanRegistry
单例 Bean 注册DefaultSingletonBeanRegistry
- 生命周期,可以分成容器生命周期和 Bean 生命周期两个小类
Lifecycle
容器生命周期的核心接口InitializingBean
,DisposableBean
等 Bean 的生命周期接口
- Bean 拓展
BeanPostProcessor
Aware
系列接口
- 上下文的接口:
ApplicationContext
作为主导接口AbstractApplicationContext
AnnotationConfigApplicationContext
的构造器的实现如下,扫描包过后,然后调
用了刷新上下文的 refresh()
方法
/** * Create a new AnnotationConfigApplicationContext, scanning for components * in the given packages, registering bean definitions for those components, * and automatically refreshing the context. * @param basePackages the packages to scan for component classes */ public AnnotationConfigApplicationContext(String... basePackages) { this(); scan(basePackages); refresh(); }
4.3 刷新应用上下文: refresh()
方法
4.3.1 refresh()
方法总览
该 refresh()
方法实现了 Spring 的 Bean 管理的全周期的流程,其中调用了 15
个辅助方法,它的主要实现如下
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
每个方法的解释如下
prepareRefresh()
刷新应用上下文的准备工作- 验证系统变量等
obtainFreshBeanFactory()
初始化 BeanFactory, 填充 BeanFactory 的属性- 创建 BeanFactory
- 加载 BeanDefinition
prepareBeanFactory(beanFactory)
准备当前上下文的 BeanFactory@Qualifier
,@Autowired
注解支持
postProcessBeanFactory(beanFactory)
的实现该方法来扩展其功能,即子类重 写当前方法来改变 BeanFactory 的功能invokeBeanFactoryPostProcessors(beanFactory)
唤醒 BeanFactoryPostProcessor 的后置处理方法- 调用
postProcessBeanFactory(...)
方法
- 调用
registerBeanPostProcessors(beanFactory)
注册 BeanPostProcessor 的拦截器- 拦截器在这里只是注册
- 调用拦截器在
getBean(...)
中实现
initMessageSource()
初始化不同语言的消息,提供国际化支持initApplicationEventMulticaster()
初始化消息多播器- 将 Bean 放入
applicationEventMulticaster
中
- 将 Bean 放入
onRefresh()
提供子类的扩展接入点registerListeners()
注册监听器,在所有注册的 Bean 中查找 listenerBean, 并将 listenerBean 添加到 applicationEventMulticaster 中finishBeanFactoryInitialization(beanFactory)
初始化剩下的单例(非懒加 载的)finishRefresh()
完成刷新过程,发布 ContextRefreshedEvent- 如果出现异常
destroyBeans()
销毁 BeancancelRefresh(ex)
重置 active 标注
- 最终结束,
resetCommonCaches()
清空缓存
4.3.2 环境准备
该部分主要包括以下几类工作
- 设置一下系统启动时间
initPropertySources()
提供个性化初始属性功能getEnvironment().validateRequiredProperties()
对系统属性进行校验- 准备一些监听器 ApplicationListener
/** * Prepare this context for refreshing, setting its startup date and * active flag as well as performing any initialization of property sources. */ protected void prepareRefresh() { // Switch to active. this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } } // Initialize any placeholder property sources in the context environment. initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // Store pre-refresh ApplicationListeners... if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // Reset local application listeners to pre-refresh state. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); }
4.3.3 加载 BeanFactory
ApplicationContext 是对 BeanFactory 的扩展,这里调用
obtainFreshBeanFactory()
方法获取 BeanFactory,但实际加载 BeanFactory 的实
现在 BeanFactory 中已经实现,通过之前对 BeanDefinition 加载分析知道
AbstractRefreshableApplicationContext
中的 refreshBeanFactory()
方法实现
了初始化 BeanFactory 的功能
/** * This implementation performs an actual refresh of this context's underlying * bean factory, shutting down the previous bean factory (if any) and * initializing a fresh bean factory for the next phase of the context's lifecycle. */ @Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
该方法功能如下
- 调用
createBeanFactory()
方法创建DefaultListableBeanFactory
- 指定序列化 ID
- 配置自定义的 BeanFactory 参数
- 加载 BeanDefinition
- 设置全局的 beanFactory 类实例
4.3.4 BeanFactory 准备工作
该项功能在 prepareBeanFactory(beanFactory)
函数中完成,它的实现如下
/** * Configure the factory's standard context characteristics, * such as the context's ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure */ protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
该方法做了以下工作
- 配置 beanFactory 的内部环境,使 beanFactory 使用当前 ApplicationContext
的上下文,具体包括
- 设置 beanFactory 的类加载器
- 设置 beanFactory 对 SPEL 语言的支持
- 设置 beanFactory 对属性编辑器的支持
- 配置 beanFactory 的 ApplicationContext 回调函数
- 设置
ApplicationContextAwareProcessor
后置处理器 - 忽略下列自动装配忽略的 Aware 接口,因为这些接口在
ApplicationContextAwareProcessor
已经进行处理- EnvironmentAware
- EmbeddedValueResolverAware
- ResourceLoaderAware
- ApplicationEventPublisherAware
- MessageSourceAware
- ApplicationContextAware
- 设置
- 配置几个特殊装配的规则
- 添加 ApplicationListenerDetector
- 添加对 AspectJ 的支持
- 将相关环境变量及系统属性以单例模式注册
4.3.5 BeanFactory 后续处理工作
调用 postProcessBeanFactory
, 其中 postProcessBeanFactory
是一个空方法,
目的是为 BeanFactory 的后置处理器提供扩展接口
/** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for registering special * BeanPostProcessors etc in certain ApplicationContext implementations. * @param beanFactory the bean factory used by the application context */ protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }
调用 invokeBeanFactoryPostProcessors()
唤醒注册的 BeanFactoryPostProcessor
/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. */ 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())); } }
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { 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. 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); } } 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! 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<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); 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(); }
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...)
方
法完成唤醒后置处理,它将 BeanFactoryPostProcessor 分成两类
- regularPostProcessors 记录的
BeanFactoryPostProcessor
后置处理器 - registryProcessors 记录的
BeanDefinitionRegistry
后置处理器 - 在唤醒时还需要考虑后置处理器的顺序
- PriorityOrdered 优先序的
- Ordered 有序的
- Non-Ordered 无序的
注册 BeanPostProcessor registerBeanPostProcessors(beanFactory)
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { 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. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); 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); 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. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); 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). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
处理国际化消息 initMessageSource()
, 这部分不重要,可以跳过
/** * Initialize the MessageSource. * Use parent's if none defined in this context. */ protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // Make MessageSource aware of parent MessageSource. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { // Only set parent context as parent MessageSource if no parent MessageSource // registered already. hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } } else { // Use empty MessageSource to be able to accept getMessage calls. DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isTraceEnabled()) { logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); } } }
调用 initApplicationEventMulticaster()
初始化多播,初始化多播属性
applicationEventMulticaster, 如果存在直接设置多播器,如果不存在则创建
/** * Initialize the ApplicationEventMulticaster. * Uses SimpleApplicationEventMulticaster if none defined in the context. * @see org.springframework.context.event.SimpleApplicationEventMulticaster */ protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isTraceEnabled()) { logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isTraceEnabled()) { logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " + "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]"); } } }
onRefresh()
是一个空方法,提供子类刷新的扩展点
protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. }
registerListeners()
获取多播器,然后注册 listener 监听器
/** * Add beans that implement ApplicationListener as listeners. * Doesn't affect other listeners, which can be added without being beans. */ protected void registerListeners() { // Register statically specified listeners first. for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
4.3.6 初始化非延迟加载单例
非延迟加载单例可以在 Spring 启动后就进行创建,然后下次加载可以快速获取,减少 创建的时间
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
preInstantiateSingletons()
方法一次性初始化所有的初始化非延迟加载单例
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
4.3.7 完成上下文刷新
finishRefresh()
完成上下文的刷新
/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * {@link org.springframework.context.event.ContextRefreshedEvent}. */ protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). clearResourceCaches(); // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // Publish the final event. publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
首先调用 clearResourceCaches()
方法清理资源的缓存
接着 initLifecycleProcessor()
初始化生命周期的处理器,该方法主要是初始化了
LifecycleProcessor
类
/** * Initialize the LifecycleProcessor. * Uses DefaultLifecycleProcessor if none defined in the context. * @see org.springframework.context.support.DefaultLifecycleProcessor */ protected void initLifecycleProcessor() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) { this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class); if (logger.isTraceEnabled()) { logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]"); } } else { DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor(); defaultProcessor.setBeanFactory(beanFactory); this.lifecycleProcessor = defaultProcessor; beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor); if (logger.isTraceEnabled()) { logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " + "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]"); } } }
调用 getLifecycleProcessor().onRefresh()
方法传播更新状态
调用 publishEvent(...)
方法发布事件
- 发布 ContextRefreshedEvent 事件
- 如果父 ApplicationContext 存在,将事件传播到父 ApplicationContext 中
/** * Publish the given event to all listeners. * @param event the event to publish (may be an {@link ApplicationEvent} * or a payload object to be turned into a {@link PayloadApplicationEvent}) * @param eventType the resolved event type, if known * @since 4.2 */ protected void publishEvent(Object event, @Nullable ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); // Decorate event as an ApplicationEvent if necessary ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType(); } } // Multicast right now if possible - or lazily once the multicaster is initialized if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // Publish event via parent context as well... if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
5 AOP 面向切面编程
5.1 AOP 预备知识
5.1.1 AOP 核心概念
AOP 叫做面向切面编程,他是一个编程范式,目的就是提高代码的模块性。Spring AOP 基于动态代理的方式实现,如果是实现了接口的话就会使用 JDK 动态代理,反之则使 用 CGLIB 代理,Spring 中 AOP 的应用主要体现在 事务、日志、异常处理等方面,通 过在代码的前后做一些增强处理,可以实现对业务逻辑的隔离,提高代码的模块化能力, 同时也是解耦。
- Aspect: 切面,由一系列切点、增强和引入组成的模块对象,可定义优先级,从而 影响增强和引入的执行顺序。事务管理在 Java 企业应用中就是一个很好的切面样例
- Join point: 接入点,程序执行期的一个点,例如方法执行、类初始化、异常处理。 在 Spring AOP 中,接入点始终表示方法执行
- Advice: 增强,切面在特定接入点的执行动作,包括 Around, Before 和 After 等 多种类型。包含 Spring 在内的许多 AOP 框架,通常会使用拦截器来实现增强,围 绕着接入点维护着一个拦截器链
- Pointcut: 切点,用来匹配特定接入点的谓词表达式,增强将会与切点表达式产生 关联,并运行在任何切点匹配到的接入点上。通过切点表达式匹配接入点是 AOP 的 核心,Spring 默认使用 AspectJ 的切点表达式
- Introduction: 引入,为某个 Type 声明额外的方法和字段。Spring AOP 允许你引 入任何接口以及它的默认实现到被增强对象上
- Target object: 目标对象,被一个或多个切面增强的对象。也叫作被增强对象。既 然 Spring AOP 使用运行时代理,那么目标对象就总是代理对象
- AOP proxy: AOP 代理,为了实现切面功能一个对象会被 AOP 框架创建出来。
- Weaving:织入,将一个或多个切面与类或对象链接在一起创建一个被增强对象。织 入能发生在编译时 ,加载时或运行时。Spring AOP 默认就是运行时织入,可以通 过枚举 AdviceMode 来设置
5.1.2 JDK 动态代理和 cglib 动态代理
使用动态代理实现主要使用下面两种方法
- JDK 动态代理
其代理对象必须是某个接口的实现
@CallerSensitive public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {...}
- 它是通过运行期间创建一个接口的实现类来完成对目标对象的代理
- cglib 动态代理
- 原理类似 JDK 动态代理,只是它在运行期间创建的代理对象是针对目标类扩展的 子类
- cglib 底层基于 ASM 开源 Java 字节码编辑类库实现,通过修改字节码生成成成 一个子类,然后重写父类的方法,实现对代码的增强
- 性能优于 JDK 动态代理
- 常见 XML 设置属性
- proxy-target-class 属性
- 属性值决定是基于接口的还是基于类的代理被创建。
proxy-target-class="true"
基于类的代理将起作用(需要 cglib 库)proxy-target-class="false"
标准的 JDK 基于接口的代理将起作用- 在 Spring 事务, AOP, 缓存这几块都有设置,其作用都是一样的
- expose-class 属性
- 通过 ThreadLocal 暴露 AOP 代理对象
this.b();
修改为((AService) AopContext.currentProxy()).b();
来显 示调用- 开启新的事务最好写在另外一个 Service 中, 将传播机制设为
REQUIRE_NEW
- proxy-target-class 属性
5.1.3 Spring AOP 和 AspectJ 的区别
- Spring AOP 基于动态代理实现,属于运行时增强
- AspectJ 则属于编译时增强,主要有 3 种方式
- 编译时织入: 指的是增强的代码和源代码我们都有,直接使用 AspectJ 编译器 编译就行,编译之后生成一个新的类,他也会作为一个正常的 Java 类装载到 JVM 虚拟机中
- 编译后织入: 指的是代码已经被编译成 class 文件或者已经打成 jar 包,这 时候要增强的话,就是编译后织入,比如你依赖了第三方的类库,又想对他增强 的话,就可以通过这种方式
- 加载时织入: 指的是在 JVM 加载类的时候进行织入
- 总结下来的话,就是 Spring AOP 只能在运行时织入,不需要单独编译,性能相比 AspectJ 编译织入的方式慢,而 AspectJ 只支持编译前后和类加载时织入,性能更 好, 功能更加强大
5.1.4 AOP 组件
PointCut 接口的定义如下
// 切入点 public interface Pointcut { ClassFilter getClassFilter(); MethodMatcher getMethodMatcher(); } // 类过滤器 public interface ClassFilter { boolean matches(Class clazz); } // 方法过滤器 public interface MethodMatcher { boolean matches(Method m, Class targetClass); boolean isRuntime(); boolean matches(Method m, Class targetClass, Object[] args); }
Advisor 及 Advice 的接口定义如下
// 增加器 public interface Advisor { Advice EMPTY_ADVICE = new Advice() {}; Advice getAdvice(); boolean isPerInstance(); } // 增强 public interface Advice {} public interface BeforeAdvice extends Advice {} public interface AfterAdvice extends Advice {}
5.1.5 AOP 实践案例
添加日志的 Bean 对象
package io.github.jeanhwea.app07_aop.beans; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class LogEntry { @Value("Hello in LogEntry") private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public void say() { System.out.println("say: " + message); } }
添加 Aspect 对象,对象中包含如下组件
@Aspect
注解当前类为 Aspect@EnableAspectJAutoProxy
需要开启自动 Aspect 代理@Pointcut("execution(* *.say(..))")
添加切入点- 添加增强方法
@Before("say()")
前置执行函数@After("say()")
后置执行函数@Around("say()")
环绕执行函数
package io.github.jeanhwea.app07_aop.beans; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component; @Aspect @Component @EnableAspectJAutoProxy public class LogEntryAspect { @Pointcut("execution(* *.say(..))") public void say() {} @Before("say()") public void beforeSay() { System.out.println("beforeSay"); } @After("say()") public void afterSay() { System.out.println("afterSay"); } @Around("say()") public Object aroundSay(ProceedingJoinPoint point) { System.out.println("aroundSay/preActions"); Object obj = null; try { obj = point.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("aroundSay/postActions"); return obj; } }
5.2 AOP 实现原理
5.2.1 AOP 的工具类 AopNamespaceUtils
AopNamespaceUtils
实现了 AOP 的常用方法
registerAutoProxyCreatorIfNecessary(...)
注册 AOP 代理创建器registerAspectJAutoProxyCreatorIfNecessary(...)
注册 AspectJ 代理创建器
public abstract class AopNamespaceUtils { /** * The {@code proxy-target-class} attribute as found on AOP-related XML tags. */ public static final String PROXY_TARGET_CLASS_ATTRIBUTE = "proxy-target-class"; /** * The {@code expose-proxy} attribute as found on AOP-related XML tags. */ private static final String EXPOSE_PROXY_ATTRIBUTE = "expose-proxy"; public static void registerAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) { BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); registerComponentIfNecessary(beanDefinition, parserContext); } public static void registerAspectJAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) { BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); registerComponentIfNecessary(beanDefinition, parserContext); } public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) { BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); registerComponentIfNecessary(beanDefinition, parserContext); } private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) { if (sourceElement != null) { boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE)); if (proxyTargetClass) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE)); if (exposeProxy) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } private static void registerComponentIfNecessary(@Nullable BeanDefinition beanDefinition, ParserContext parserContext) { if (beanDefinition != null) { parserContext.registerComponent( new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME)); } } }
5.2.2 AOP 代理是否开启 AspectJAutoProxyRegistrar
AspectJAutoProxyRegistrar
类实现了扫描是否开启自动进行 AOP 代理其实现如下
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { /** * Register, escalate, and configure the AspectJ auto proxy creator based on the value * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing * {@code @Configuration} class. */ @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }
该方法实现逻辑如下
- 扫描是否开启 AOP 自动代理开关
- 如果开启则创建 AspectJ 的代理创建器
- 并且配置
proxyTargetClass
和exposeProxy
属性
进入 registerBeanDefinitions(...)
方法里面可以看出
registerOrEscalateApcAsRequired:123, AopConfigUtils (org.springframework.aop.config) registerAspectJAnnotationAutoProxyCreatorIfNecessary:100, AopConfigUtils (org.springframework.aop.config) registerAspectJAnnotationAutoProxyCreatorIfNecessary:93, AopConfigUtils (org.springframework.aop.config) registerBeanDefinitions:45, AspectJAutoProxyRegistrar (org.springframework.context.annotation) registerBeanDefinitions:86, ImportBeanDefinitionRegistrar (org.springframework.context.annotation) lambda$loadBeanDefinitionsFromRegistrars$1:385, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation) accept:-1, 1233990028 (org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$$Lambda$45) forEach:684, LinkedHashMap (java.util) loadBeanDefinitionsFromRegistrars:384, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation) loadBeanDefinitionsForConfigurationClass:148, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation) loadBeanDefinitions:120, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation) processConfigBeanDefinitions:331, ConfigurationClassPostProcessor (org.springframework.context.annotation) postProcessBeanDefinitionRegistry:236, ConfigurationClassPostProcessor (org.springframework.context.annotation) invokeBeanDefinitionRegistryPostProcessors:275, PostProcessorRegistrationDelegate (org.springframework.context.support) invokeBeanFactoryPostProcessors:95, PostProcessorRegistrationDelegate (org.springframework.context.support) invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support) refresh:532, AbstractApplicationContext (org.springframework.context.support) <init>:101, AnnotationConfigApplicationContext (org.springframework.context.annotation) main:9, MyApp07 (io.github.jeanhwea.app07_aop)
registerOrEscalateApcAsRequired(...)
的实现如下
@Nullable private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
- 如果存在自动代理创建器
- 通过优先级判断需要使用哪个创建器
- 如果 currentPriority 小于 requiredPriority 则需要修改 Bean 的
- 否则设置默认优先级等 BeanDefinition 参数
注意 AUTO_PROXY_CREATOR_BEAN_NAME 的值为
/** * The bean name of the internally managed auto-proxy creator. */ public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
- 这里给容器中注册一个
AnnotationAwareAspectJAutoProxyCreator
5.2.3 AspectJ 创建器 AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
是自动创建 AspectJ 代理类的创建器,
该类的概览如下
org.springframework.aop.aspectj.annotation Class AnnotationAwareAspectJAutoProxyCreator java.lang.Object org.springframework.aop.framework.ProxyConfig org.springframework.aop.framework.ProxyProcessorSupport org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator All Implemented Interfaces: Serializable, AopInfrastructureBean, org.springframework.beans.factory.Aware, org.springframework.beans.factory.BeanClassLoaderAware, org.springframework.beans.factory.BeanFactoryAware, org.springframework.beans.factory.config.BeanPostProcessor, org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor, org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor, org.springframework.core.Ordered
AbstractAutoProxyCreator
实现了 AOP 的核心方法- 实现了
BeanFactoryAware
和BeanPostProcessor
接口 createProxy(...)
创建代理类buildAdvisors(...)
通过传入的 Bean 来创建 AdvisorwrapIfNecessary(...)
包裹 Bean 方法,添加代理包裹信息isInfrastructureClass(...)
- 判断是否是
Advice
,PointCut
,Advisor
或AopInfrastructureBean
- InfrastructureClass 需要添加 AOP 代理
- 判断是否是
- 实现了
InstantiationAwareBeanPostProcessor
接口包含类实例化和初始化前后的构造函数postProcessBeforeInstantiation(...)
实例化前调用的代理类创建方法postProcessAfterInitialization(...)
初始化后调用的代理类创建方法postProcessAfterInstantiation(...)
实例化后调用的代理类创建方法postProcessBeforeInitialization(...)
初始化前调用的代理类创建方法
AbstractAdvisorAutoProxyCreator
包括 Advisor 的创建方法getAdvicesAndAdvisorsForBean(...)
查找 Bean 的 AdvisorfindEligibleAdvisors(...)
获取 Bean 所需的合适的 AdvisorfindAdvisorsThatCanApply(...)
获取可以应用的 Advisor
AspectJAwareAdvisorAutoProxyCreator
- 类似
AbstractAdvisorAutoProxyCreator
, 针对 AspectJ 进行扩展 AbstractAdvisorAutoProxyCreator
是抽象类,AspectJAwareAdvisorAutoProxyCreator
是类
- 类似
AnnotationAwareAspectJAutoProxyCreator
- 添加对注解 Aspect 的扩展
5.2.4 AbstractAutoProxyCreator
提前埋点
实例化前 getAdvicesAndAdvisorsForBean(...)
创建 Bean 的增强器
@Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // Create proxy here if we have a custom TargetSource. // Suppresses unnecessary default instantiation of the target bean: // The TargetSource will handle target instances in a custom fashion. TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; }
初始化后调用 wrapIfNecessary(...)
进行 Bean 的包裹,这里会调用
createProxy(...)
方法创建代理类
/** * Create a proxy with the configured interceptors if the bean is * identified as one to proxy by the subclass. * @see #getAdvicesAndAdvisorsForBean */ @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
5.2.5 XML 方式的 AOP 读取
<aspectj-autoproxy/>
自动注解 AopNamespaceHandler
类中添加自动注解标签
public class AopNamespaceHandler extends NamespaceHandlerSupport { /** * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}' * and '{@code scoped-proxy}' tags. */ @Override public void init() { // In 2.0 XSD as well as in 2.1 XSD. registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace as of 2.1 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); } }
NamespaceHandler
提供 BeanDefinitionParser
的 <aop:config>
标签支持,例
如接入地 <pointcut/>
标签的定义
<aop:pointcut id="getNameCalls" expression="execution(* *..ITestBean.getName(..))"/>
增强器 <advisor/>
标签的定义
<aop:advisor id="getAgeAdvisor" pointcut="execution(* *..ITestBean.getAge(..))" advice-ref="getAgeCounter"/> <aop:advisor id="getNameAdvisor" pointcut-ref="getNameCalls" advice-ref="getNameCounter"/>
所有的解析器需要实现 BeanDefinitionParser
接口,入口函数为 parse(...)
方
法,而对 AspectJ 的解析器实现的源码如下
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser { @Override @Nullable public BeanDefinition parse(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); extendBeanDefinition(element, parserContext); return null; } private void extendBeanDefinition(Element element, ParserContext parserContext) { BeanDefinition beanDef = parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME); if (element.hasChildNodes()) { addIncludePatterns(element, parserContext, beanDef); } } private void addIncludePatterns(Element element, ParserContext parserContext, BeanDefinition beanDef) { ManagedList<TypedStringValue> includePatterns = new ManagedList<>(); NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node instanceof Element) { Element includeElement = (Element) node; TypedStringValue valueHolder = new TypedStringValue(includeElement.getAttribute("name")); valueHolder.setSource(parserContext.extractSource(includeElement)); includePatterns.add(valueHolder); } } if (!includePatterns.isEmpty()) { includePatterns.setSource(parserContext.extractSource(element)); beanDef.getPropertyValues().add("includePatterns", includePatterns); } } }
5.3 创建 AOP 代理
5.3.1 创建 AOP 代理
创建代理类的调用栈如下,最终通过 createAopProxy
方法创建 JDK 动态代理或
cglib 动态代理
createAopProxy:51, DefaultAopProxyFactory (org.springframework.aop.framework) createAopProxy:105, ProxyCreatorSupport (org.springframework.aop.framework) getProxy:110, ProxyFactory (org.springframework.aop.framework) createProxy:471, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy) wrapIfNecessary:350, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy) postProcessAfterInitialization:299, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy) applyBeanPostProcessorsAfterInitialization:431, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) initializeBean:1800, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:595, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 1625082366 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$37) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support) preInstantiateSingletons:882, DefaultListableBeanFactory (org.springframework.beans.factory.support) finishBeanFactoryInitialization:878, AbstractApplicationContext (org.springframework.context.support) refresh:550, AbstractApplicationContext (org.springframework.context.support) <init>:101, AnnotationConfigApplicationContext (org.springframework.context.annotation) main:9, MyApp07 (io.github.jeanhwea.app07_aop)
创建 AOP 代理嵌套了好几层,最终调用 DefaultAopProxyFactory
的
createAopProxy(...)
方法的实现,这里可以
- 如果目标对象实现了接口,默认采用 JDK 动态代理实现 AOP
- 如果目标对象实现了接口,可以强制使用 cglib 实现 AOP
- 如果目标对象没有实现了接口,必须采用 cglib 实现 AOP,Spring 会自动在 JDK 动态代理和 cglib 中切换
@SuppressWarnings("serial") public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } /** * Determine whether the supplied {@link AdvisedSupport} has only the * {@link org.springframework.aop.SpringProxy} interface specified * (or no proxy interfaces specified at all). */ private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) { Class<?>[] ifcs = config.getProxiedInterfaces(); return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]))); } }
postProcessAfterInitialization(...)
方法中调用了 wrapIfNecessary(...)
方
法获取包裹 Bean 对象,该方法有以下作用
- 前置判断是否需要创建增强器
- 如果存在增强方法
getAdvicesAndAdvisorsForBean(...)
获取拦截器,如果有拦截器说明该方法 需要增强
- 调用
createProxy(...)
方法创建代理类,并返回代理对象
/** * Wrap the given bean if necessary, i.e. if it is eligible for being proxied. * @param bean the raw bean instance * @param beanName the name of the bean * @param cacheKey the cache key for metadata access * @return a proxy wrapping the bean, or the raw bean instance as-is */ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
createProxy(...)
方法逻辑如下
- 获取增强方法或者增强器
- 根据获取的增强进行代理
/** * Create an AOP proxy for the given bean. * @param beanClass the class of the bean * @param beanName the name of the bean * @param specificInterceptors the set of interceptors that is * specific to this bean (may be empty, but not null) * @param targetSource the TargetSource for the proxy, * already pre-configured to access the bean * @return the AOP proxy for the bean * @see #buildAdvisors */ protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }
5.3.2 获取增强器 Advisor
获取增强器的最终调用方法为 buildAspectJAdvisors(...)
buildAspectJAdvisors:84, BeanFactoryAspectJAdvisorsBuilder (org.springframework.aop.aspectj.annotation) findCandidateAdvisors:95, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation) shouldSkip:101, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy) wrapIfNecessary:341, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy) postProcessAfterInitialization:299, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy) applyBeanPostProcessorsAfterInitialization:431, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) initializeBean:1800, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) doCreateBean:595, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) createBean:517, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) lambda$doGetBean$0:323, AbstractBeanFactory (org.springframework.beans.factory.support) getObject:-1, 343856911 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$37) getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support) doGetBean:321, AbstractBeanFactory (org.springframework.beans.factory.support) getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support) preInstantiateSingletons:882, DefaultListableBeanFactory (org.springframework.beans.factory.support) finishBeanFactoryInitialization:878, AbstractApplicationContext (org.springframework.context.support) refresh:550, AbstractApplicationContext (org.springframework.context.support) <init>:101, AnnotationConfigApplicationContext (org.springframework.context.annotation) main:9, MyApp07 (io.github.jeanhwea.app07_aop)
该方法的实现流程如下:
- 获取所有的 beanName, 在这一步骤中将 beanFactory 中注册的 Bean 都提取出来
- 遍历所以 beanName, 并找出声明 AspectJ 注解的类
- 对标记为 AspectJ 注解的类进行增强器提取
this.advisorFactory.getAdvisors(factory)
- 将提取的结果加入缓存
this.advisorsCache.put(...)
/** * Look for AspectJ-annotated aspect beans in the current bean factory, * and return to a list of Spring AOP Advisors representing them. * <p>Creates a Spring Advisor for each AspectJ advice method. * @return the list of {@link org.springframework.aop.Advisor} beans * @see #isEligibleBean */ public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new ArrayList<>(); aspectNames = new ArrayList<>(); String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this case they // would be cached by the Spring container but would not have been weaved. Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List<Advisor> advisors = new ArrayList<>(); for (String aspectName : aspectNames) { List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; }
调用 getAdvisors(...)
方法获取 Advisor
@Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); validate(aspectClass); // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator // so that it will only instantiate once. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>(); for (Method method : getAdvisorMethods(aspectClass)) { Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } // Find introduction fields. for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }
6 SpringBoot 自动装配
7 参考链接
- Spring Framework on Github
- Spring Framework Documentation
- source-code-hounter 互联网公司常用框架源码赏析
- Spring Analysis Spring 框架分析
- Small Spring