# IoC
# XML配置
同一id的Bean对象在容器中的实例,默认作用域为
singleton
饿汉式单例(容器创建时就完成单例对象的创建),prototype
为懒汉式多例(容器创建时不对对象进行创建),每次获取都会创建新的对象实例。单例模式下对象创建后调用init-method
,容器销毁后调用destroy-method
;原型模式下容器销毁后不会调用destroy-method
(使用
<property>
标签)对象初始化将调用无参构造器,并借助对象的setter方法为对象属性赋值;(使用<constructor-arg>
标签)可改为使用含参构造器对对象进行直接初始化和赋值,若存在重载的构造器,则使用标签中的type
属性指定装填参数的类型若不同Bean对象的类型相同,则不能通过
getBean(类型)
方法获取特定Bean通过静态工厂创建Bean对象;通过实例工厂创建Bean对象(通过工厂方法);通过
FactoryBean<T>
实现类创建Bean对象(懒汉式)<context:property-placeholder location="">
标签为Bean加载外部配置文件泛型依赖注入
# 注解配置
向容器注入Bean
@Bean
@Import
(通过ImportSelector
或BeanDefinitionRegistrar
手动导入特定bean)- 实现
FactoryBean
手动注册
Bean生命周期方法
@Bean
注解中手动指定initMethod
与destroyMethod
属性- 实现
InitializingBean
/DisposableBean
指定初始化与销毁方法 @PostConstruct
/@PreDestroy
- 实现
BeanPostProcessor
拦截容器所有对象的生命周期行为
ApplicationContextAwareProcessor
InitDestroyAnnotationBeanPostProcessor
BeanValidationBeanPostProcessor
AsyncAnnotationBeanPostProcessor
容器组件装配
@Autowired
优先通过Bean类型在容器中搜索组件,若找到多个则通过Bean名称(或通过@Qualifier
显式指定的Bean名称)进行进一步装配;若最终未找到相应组件,默认抛出异常(@Autowired(required=true)
)可标注在属性、Setter方法、构造器方法(或方法参数)上
- 若组件只有一个有参构造器,则参数默认从容器中获取,无需标注
@Autowired
- 通过
@Bean
手动注入组件时,方法参数(如果存在)默认从容器中获取,无需标注@Autowired
@Resource
只能按照Bean名称进行组件装配
# 生命周期
# ApplicationContext生命周期
// AbstractApplicationContext.java
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();
initPropertySource();
供子类重写以构造个性化属性(如用于自定义配置中心)getEnvironment().validateRequiredProperties();
检验个性化属性的合法性earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
保存容器中的部分早期事件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
refreshBeanFactory();
刷新(或创建❓)BeanFactory
getBeanFactory();
返回刚初始化的DefaultListableBeanFactory
#
prepareBeanFactory(beanFactory);
- 配置
BeanFactory
类加载器、表达式解析器、环境变量信息Map等组件 - 配置
ApplicationContextAwareProcessor
- 忽略对
EnvironmentAware
、EmbeddedValueResolveAware
实现类的自动配置;设置对BeanFactory
、ResourceLoader
、ApplicationEventPublisher
、ApplicationContext
组件的自动配置 - 配置
ApplicationListenerDetector
- 配置
#
postProcessBeanFactory(beanFactory);
postProcessBeanFactory();
供子类重写以在容器预初始化完成时进行进一步的设置
#
invokeBeanFactoryPostProcessors(beanFactory);
在
BeanFactory
标准初始化之后执行:- 根据是否实现了
PriorityOrdered
、Order
接口分批获取容器中所有的BeanDefinitionRegistryPostProcessor
,分批排序后分批执行:invokeBeanDefinitionRegistryPostProcessors(Collection, BeanFactory);
执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
invokeBeanFactoryPostProcessors(Collection, BeanFactory);
执行BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()
- 分批获取容器中所有的
BeanFactoryPostProcessor
,分批排序后分批执行:invokeBeanFactoryPostProcessors(Collection, BeanFactory);
执行BeanFactoryPostProcessor.postProcessBeanFactory()
- 根据是否实现了
#
registerBeanPostProcessors(beanFactory);
调用
PostProcessorRegistrationDelegate
的同名方法完成Bean后置处理器的注册- 通过类型获取容器中所有已定义但未被创建的
BeanPostProcessor
,并进行统计与检查(BeanPostPrcessorChecker
) - 分批获取容器中所有的
BeanPostProcessor
,分批排序后分批注册进BeanFactory
- 最后注册
MergedBeanDefinitionPostProcessor
与ApplicationListenerDetector
(在Bean初始化结束后将ApplicationListener
的实现类作为应用监听器组件加入容器)
- 通过类型获取容器中所有已定义但未被创建的
initMessageSource();
初始化用于消息绑定与消息解析的MessageSource
组件initApplicationEventMulticaster();
初始化事件派发器#
onRefresh();
onRefresh();
供子类重写以向容器中注册其他组件❓
registerListeners();
将容器中的所有应用监听器注册在事件派发器上,并调用multicastEvent(ApplicationEvent)
派发可能存在的早期事件#
finishBeanFactoryInitialization(beanFactory);
- ...
preInstantiateSingletons();
完成自定义非懒加载单例Bean的初始化
#
finishRefresh();
initLifecycleProcessor();
获取容器生命周期处理器和以对容器onRefresh()
及onClose()
等生命周期方法进行拦截getLifecycleProcessor.onRefresh();
publishEvent(new ContextRefreshedEvent(this));
发布容器刷新完成事件- ...
# Bean生命周期
# 容器的创建与Bean的获取(Spring 4.x)
执行
ClassPathXmlApplicationContext(String[] configurations, boolean refresh, ApplicationContext parent)
或AnnotationConfigApplicationContext(String[] configurations, boolean refresh, ApplicationContext parent)
构造器执行
AbstractApplicationContext.refresh()
方法:解析配置文件,读取Bean的配置信息并保存在ConfigurableListableBeanFactory
对象中:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
在
AbstractApplicationContext.finishBeanFactoryInitialization(BeanFactory beanFactory)
内的最后一步:DefaultListableBeanFactory.preInstantiateSingletons()
中完成用户自定义非懒加载的单实例Bean的初始化:// DefaultListableBeanFactory.preInstantiateSingletons() List<String> beanNames; synchronized(this.beanDefinitionMap) { // 获取所有将要创建的Bean实例名称 beanNames = new ArrayList<String>(this.beanDefinitionMap); for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 依次创建(非抽象、单实例、非懒加载的)Bean实例 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { // 利用重写的BeanFactory.getBean(String beanName)创建Bean //final BeanFactory<?> factory = (FactoryBean<?>) getBean(...) // boolean isEagerInit; // ... } else { // 调用父类doGetBean()方法创建Bean getBean(beanName); } } } } // SmartInitializingSingleton子类事件的监听处理器 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { // ... } else { smartSingleton.afterSingletonInstantiated(); } } }
DefaultListableBeanFactory.getBean(String beanName)
中调用父类doGetBean(..)
:// AbstractBeanFactory.doGetBean(String name, Class<T> requiredType, Object[] args, boolean typeCheckOnly) // ... Object sharedInstance = getSingleton(beanName); // 尝试从单实例Bean缓存(ConcurrentHashMap<String, Object> singletonObjects,单例池)中尝试获取已经创建完成的Bean实例 if (sharedInstance != null && args == null) { // 已找到先前创建的Bean实例 // ... } else { // 未找到先前创建的Bean实例 // ... markBeanAsCreated(beanName); try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // ... // 获取依赖Bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { // 存在依赖Bean,则递归调用getBean(String beanName)对其进行创建 // ... } if (mbd.isSingleton()) { // ... sharedInstance = getSingleton(beanName, new ObjectFactory<Object> { @Override public Object getObject() { try { return createBean(beanName, mbd, args); // 真正实现Bean实例的初始化 } } } } } }
# Spring如何解决循环依赖?
答:Spring通过三级缓存解决了循环依赖,其中一级缓存为单例池
singletonObjects
,二级缓存为早期曝光对象earlySingletonObjects
,三级缓存为单例对象工厂singletonFactories
。当A、B两个类发生循环引用时,在A完成实例化后,使用实例化后的对象创建对象工厂,并添加到三级缓存中:如果A被AOP代理,那么工厂中的是A代理后的对象,如果A没有被AOP代理,那么工厂中的是A原本实例化的对象。
当A在初始化过程中进行属性注入时,会进行B的创建,由于B依赖了A,故创建B的同时又会去调用
getBean(a)
来获取A,此时会从三级缓存中进行获取(尚未初始化完成的A):- 先获取三级缓存中的对象工厂
- 调用对象工厂的
getObject()
方法获取A,将其注入到B中。此后B完成后续的初始化流程
A等待B初始化完成后将B再注入到属性中,此时A完成后续的初始化流程
至此,循环依赖结束
# 为什么要使用三级缓存呢?二级缓存能解决循环依赖吗?
答:如果使用二级缓存解决循环依赖,所有Bean在实例化后(而非初始化阶段)就必须完成AOP代理,这样违背了Spring设计的原则:即,Spring应通过
AnnotationAwareAspectJAutoProxyCreator
后置处理器在Bean生命周期的最后一步实现AOP代理,而非在实例化后就立即进行AOP代理// DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory) 将初始化完成的Bean单例加入容器 synchronized(this.singletonObjects) { // 用ConcurrentHashMap对单实例的Bean对象进行缓存(beanName -> beanInstance) Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { // ... try { // Bean实例的获取 singletonObject = singletonFactory.getObject(); // ... } finally { afterSingletonCreation(beanName, singletonObject); } // ... // 将Bean对象加入单实例Bean缓存(singletonObjects,单例池)中 addSingleton(beanName, singletonObject); } }
# Bean实例化
createBean(...)
resolveBeforeInstantiation(...)
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
[实例化]
AbstractAutowireCapableBeanFactory.doCreateBean(...)
AbstractAutowireCapableBeanFactory.instantiateBean(beanName, mbd)
,推断构造方法,创建Bean对象AbstractAutowireCapableBeanFactory.populateBean(...)
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
InstantiationAwareBeanPostProcessor.postProcessPropertyValues()
InstantiationAwareBeanPostProcessor.applyPropertyValues()
// AbstractAutowireCapableBeanFactory.createBean(...)
// 【实例化前】尝试通过InstantiationAwareBeanPostProcessor获取该Bean的代理对象(InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation())
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// (成功获取代理对象)执行applyBeanPostProcessorsAfterInitialization(..)完成初始化后的收尾处理
// ...
// 【实例化前】(不能获取代理对象)开始Bean实例的创建
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
// AbstractAutowireCapableBeanFactory.doCreateBean(...)
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args); // 【实例化】借助AbstractAutowireCapableBeanFactory.instantiateBean(beanName, mbd),利用工厂方法直接获取或利用反射调用Bean对象的构造器完成原始Bean对象的初始化
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); // 遍历所有MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition()方法
}
}
}
// ...
//【实例化后】开始Bean对象的属性赋值与初始化流程
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); // 【实例化后】遍历所有InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()及postProcessPropertyValues()方法,其中前者❓,后者❓;最后执行applyPropertyValues(),借助反射调用对象Setter方法等为Bean对象属性赋值
exposedObject = initializeBean(beanName, exposedObject, args); // 【实例化后】进行Bean初始化
}
// ...
// 注册Bean对象的销毁方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
// ...
}
# Bean初始化
InstantiationAwareBeanPostProcessor.initializeBean(...)
BeanPostProcessor.postProcessBeforeInitialization()
AbstractAutowireCapableBeanFactory.invokeInitMethods(...)
- [初始化]
InitializingBean.afterPropertiesSet()
/init()
- [初始化]
BeanPostProcessor.postProcessAfterInitialization()
,尝试借助ProxyFactory
构造代理对象,并放入单例池,最终获取完整的Bean对象
// AbstractAutowireCapableBeanFactory.initializeBean(final String beanName, final Object bean, Object[] args)
if (System.getSecurityManager() != null) {
// ...
} else {
invokeAwareMethods(beanName, bean); // 【初始化前】执行部分Aware接口回调(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware);其他有对应后置处理器的Aware接口回调发生在下一步的postProcessoBeforeInitialization()中
// ...
Object wrappedBean = bean;
// ⓵
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); // 【初始化前】遍历所有BeanPostProcessors,依次执行postProcessoBeforeInitialization()方法(一旦任一个BeanPostProcessors返回null,则终止遍历)
// ...
// ⓶
invokeInitMethods(beanName, wrappedBean, mbd); //【初始化】回调初始化方法
// ...
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); // 【初始化后】遍历所有BeanPostProcessors.postProcessAfterInitialization()方法
}
⓵
// ApplicationContextAwareProcessor.postProcessBeforeInitialization(Object, String)
// 根据所实现的Aware接口类型执行不同操作
ApplicationContextAwareProcessor.invokeAwareInterfaces(Object);
⓶
// AbstractAutowireCapableBeanFactory.invokeInitMethods(...)
// 回调多种初始化方法
// 1. 是否实现InitializingBean接口(afterPropertiesSet())
// 2. 是否存在自定义init()方法
// (执行其他初始化方法)
# AOP
若被代理对象没有实现任何接口,则无法使用原生JDK动态代理,因为代理对象与被代理对象之间的唯一关联是所实现的接口
// 在InvocationHandler.invoke(Object, Method, Object[])中对目标方法进行修饰 Object proxy = Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler)
若开启AOP,则容器中保存的是组件的代理对象。若组件实现了接口,则只能通过组件的接口类型访问其代理对象(JDK动态代理);若组件未实现任何接口,则可通过组件的自身类型访问其代理对象(CGLIB动态代理)
切面类中配置通知方法
@Before
/@After
/@AfterReturning
/@AfterThrowing
/@Around
通知方法的执行顺序:前置通知->后置通知->返回/异常通知
- 通知方法注解的切入点表达式中,
public
为可选(只支持public方法)*
匹配全部路径或单层路径,..
匹配多层路径(非全部);*
匹配任意类名、任意字符或单个参数,..
匹配任意数量参数
- 通知方法注解的切入点表达式中,
在(非环绕)通知方法参数中的
JoinPoint
对象中获取通知方法的签名和参数列表等信息;在通知方法注解的returning
或throwing
属性中配置接收通知方法返回值或异常的参数(JoinPoint
对象在通知方法参数中必须位于首位)通知方法可拥有任意访问修饰符和返回值,但其参数表必须唯一确定(Spring通过反射查找该方法的唯一方式)
环绕通知优先于普通通知执行(仅在当前切面类范围内:环绕前置<->普通前置->目标方法->环绕后置->普通后置);必须将
proceedingJoinPoint.proceed(Object[] args)
结果进行返回或将异常进行抛出,否则普通通知方法无法感知通知方法的返回值或异常
若存在多个切面类,则类名字母顺序在前或
@Order
注解值越小的先执行
# 源码分析
# @EnableAspectJAutoProxy
利用BeanDefinitionRegistrar
向容器中注册AspectJAutoProxyRegistrar
,后者向BeanDefinitionRegistry
中注册AnnotationAwareAspectJAutoProxyCreator
# AnnotationAwareAspectJAutoProxyCreator
# 初始化
registerBeanPostProcessors(beanFactory);
创建所需的BeanPostProcessor,并注册进BeanFactoryfinishBeanFactoryInitialization(beanFactory);
创建剩余的单例Bean(如非后置处理器类型的其他Bean),完成BeanFactory初始化
# AOP相关类的包装
# AOP相关类的初始化
- 判断AOP关注点所在类是否已存在于缓存(
advicedBeans
)中 - 判断AOP关注点所在类是否实现了
Advice
/Pointcut
/Advisor
/AopInfrastructureBean
等基础接口,或是否标注有@Aspect
注解(是否是切面类) - 判断是否需要跳过(当该类为
AspectJPointcutAdvisor
类型时跳过) - 调用AOP关注点所在类的构造方法
# AOP相关类的初始化后
wrapIfNecessary(Object bean, String beanName, String cacheKey)
将AOP关注点所在类包装为代理对象
AbstractAdvisorAutoProxyCreator.getAdviceAndAdvisorsForBean(..)
遍历所有增强器依次判断是否匹配,获取当前Bean所有能使用的增强器并排序返回(拦截器,即通知方法)- 将当前Bean保存至
advicedBeans
- 为当前Bean创建代理对象
- 获取所有可用的增强器,保存至
proxyFactory
- 使用
proxyFactory
创建JdkDynamicAopProxy
或ObjenesisCglibAopProxy
代理对象
- 获取所有可用的增强器,保存至
# AOP的执行流程
CglibAopProxy.intercept()
DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(..)
尝试获取关注点方法的有序拦截器链(MethodInterceptor
)List<Object> getInterceptorsAndDynamicInterceptionAdvice( Advised config, Method method, @Nullable Class<?> targetClass) { // 遍历所有增强器,根据实现接口的不同包装为org.aopalliance.intercept.MethodInterceptor对象 if (advisor instanceof PointcutAdvisor) { // ... } else if (advisor instanceof IntroductionAdvisor) { // ... } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } // ... }
(若无法获取拦截器链)直接执行目标方法;
(若成功获取拦截器链)将关注点方法信息以及拦截器链包装为
CglibMethodInvocation
对象,并调用其proceed()
方法在该方法中链式获取所有可用的拦截器,执行其
invoke(CglibMethodInvocation)
方法:- 如果拦截器非
MethodBeforeAdviceInterceptor
,则继续调用CglibMethodInvocation
的proceed()
,proceed()
返回之后再执行通知方法 - 如果拦截器为
MethodBeforeAdviceInterceptor
(拦截器链最后一组),则先执行增强器的通知方法,再继续调用CglibMethodInvocation
的proceed()
:此处由于已遍历至拦截器链末尾,则调用invokeJoinpoint()
执行切入点方法
通过拦截器链,保证通知方法与切入点方法之间的执行顺序
- 如果拦截器非
# AOP自调用解决方案
# 事务
REQUIRED
SUPPORTS
MANDATORY
REQUIRES_NEW
NOT_SUPPORTED
NEVER
NESTED
# 编程式事务
PlatformTransactionManager
接口
# 声明式事务
# AbstractPlatformTransactionManager
# @EnableTransactionManagement
通过TransactionManagementConfigurationSelector
,默认向容器中导入AutoProxyRegistrar
和ProxyTransactionManagementConfiguration
,前者向容器中注册InfrastructureAdvisorAutoProxyCreator
,后者向容器中注册BeanFactoryTransactionAttributeSourceAdvisor
# BeanFactoryTransactionAttributeSourceAdvisor
- 借助
AnnotationTransactionAttributeSource
中的注解解析器解析@Transactional
注解配置信息 - 向
TransactionInterceptor
注入注解解析器与事务管理器PlatformTransactionManager
(通过@Qualifier
指定或从容器中获取事务管理器) - 在代理对象执行目标方法时,通过事务拦截器链(中的事务管理器)进行事务控制
# 扩展组件
# BeanFactoryPostProcessor
BeanFactoryPostProcessor.postProcessBeanFactory()
在BeanFactory标准初始化完成后调用,此时Bean定义信息已被加载至BeanFactory,但尚未进行实例化
# BeanDefinitionRegistryPostProcessor
在Bean定义信息将被加载至BeanFactory之前调用
先执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
,再执行BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()
,再执行BeanFactoryPostProcessor
的回调方法
用于在BeanFactory初始化完成之前向容器工厂添加额外的组件
# ApplicationListener
监听容器内发布的事件(事件继承至ApplicationEvent
)
@EventListener
借助EventListenerMethodProcessor
解析注解上的事件监听信息,而该方法处理器实现了SmartInitializingSinglton
接口
# SmartInitializingSingleton
在容器内所有非懒加载的单例Bean都初始化完成(finishBeanFactoryInitialization(beanFactory)
)后,容器结束刷新(finishRefresh()
)前调用
← JVM Spring Boot基础 →