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 入口- 常见的实现类
DefaultSingletonBeanRegistryregisterBeanDefinition(...)注册 BeanDefinitionMap<String, BeanDefinition> beanDefinitionMapregisterBeanDefinition(...)添加 BeanDefinition 到 beanDefinitionMap
- 三级缓存解决循环依赖
Map<String, Object> singletonObjectsMap<String, Object> earlySingletonObjectsMap<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 实例化后置处理方法
- 常见子接口
InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation(...)postProcessAfterInitialization(...)postProcessAfterInstantiation(...)postProcessBeforeInitialization(...)
SmartInstantiationAwareBeanPostProcessor- 继承自
InstantiationAwareBeanPostProcessor determineCandidateConstructors(...)predictBeanType(...)getEarlyBeanReference(...)
- 继承自
DestructionAwareBeanPostProcessorpostProcessBeforeDestruction(...)requiresDestruction(...)
MergedBeanDefinitionPostProcessorpostProcessMergedBeanDefinition(...)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继承自AbstractNestablePropertyAccessorAbstractNestablePropertyAccessor#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
常见的类简单可以分成以下几类
- 资源处理
ResourceSpring 中关于资源的定义ResourceLoader提供资源加载方法BeanDefinitionReader读取接口主要用来读取信息
- 注册形式,在 Spring 中关于注册的几个核心
AliasRegistry别名注册BeanDefinitionRegistryBean 定义注册SingletonBeanRegistry单例 Bean 注册DefaultSingletonBeanRegistry
- 生命周期,可以分成容器生命周期和 Bean 生命周期两个小类
Lifecycle容器生命周期的核心接口InitializingBean,DisposableBean等 Bean 的生命周期接口
- Bean 拓展
BeanPostProcessorAware系列接口
- 上下文的接口:
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