准备
接口
public interface UserService {
String query();
}
接口的实现
@Service
public class UserServiceImpl implements UserService {
@Override
public String query() {
System.out.println("------------ yz ------------");
return "yz";
}
}
切面类
@Aspect
@Component
public class AopConfig {
@Pointcut(value = "execution(* com.atguigu.springIOC.UserServiceImpl.*(..))")
public void businessService() {
}
@Before(value = "businessService()")
public void doBefore() {
System.out.println("----------------- doBefore -----------------");
}
@AfterReturning(value = "businessService()")
public void doAfterReturning() {
System.out.println("----------------- doAfterReturning -----------------");
}
@After(value = "businessService()")
public void doAfter() {
System.out.println("----------------- doAfter -----------------");
}
}
测试类
// 该注解在测试时必须添加;在使用 springboot 较高版本启动运行程序时,可以不添加
@EnableAspectJAutoProxy
@ComponentScan(basePackages = {
"com.atguigu.springIOC"})
public class BeanTest {
public static void main(String[] args) {
// 获取 spring IOC 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanTest.class);
// 从容器中获取 bean
UserService userService = (UserService) applicationContext.getBean("userServiceImpl");
String query = userService.query();
System.out.println(query);
}
}
测试结果
----------------- doBefore -----------------
------------ yz ------------
----------------- doAfter -----------------
----------------- doAfterReturning -----------------
yz
解读 spring aop
代理对象的产生
1.源码解读之前
既然要产生代理对象,我们进行源码分析,无非就是从下面两行代码入手
// 获取 spring IOC 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanTest.class);
// 从容器中获取 bean
UserService userService = (UserService) applicationContext.getBean("userServiceImpl");
对于上面的代码的 getBean
方法,它的底层逻辑是首先会从一级缓存 singletonObjects
中获取,如果没有,再根据具体的 bean
的作用域分别去完成 bean
的初始化(不考虑循环依赖情况)
通过 spring 初始化 bean(单例) 过程 的文章分析,userServiceImpl(原型 bean)
这个 bean
会通过 getBean
方法从一级缓存 singletonObjects
中能获取到。那么 userServiceImpl(原型 bean)
的代理对象肯定从下面的代码中产生
// 获取 spring IOC 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanTest.class);
2.抽象类 AbstractBeanFactory
的 doGetBean
方法
关于代码
// 获取 spring IOC 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanTest.class);
的过程,鉴于篇幅本篇文章不再详细赘述,详细过程请查看,我们从这个 doGetBean
方法开始
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
/**
* 通过 name 获取 beanName。这里不使用 name 直接作为 beanName 有两个原因
* 1、name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 本身,而非 FactoryBean
* 实现类所创建的 bean。在 BeanFactory 中,FactoryBean 的实现类和其他的 bean 存储
* 方式是一致的,即 <beanName, bean>,beanName 中是没有 & 这个字符的。所以我们需要
* 将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 实例。
* 2、还是别名的问题,转换需要 &beanName
*/
final String beanName = transformedBeanName(name);
Object bean;
// 先从缓存中获取,因为在容器初始化的时候或者其他地方调用过getBean,已经完成了初始化
Object sharedInstance = getSingleton(beanName);
// 如果已经初始化过,直接从缓存中获取
if (sharedInstance != null && args == null) {
// 如果beanName的实例存在于缓存中
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/**
* 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果
* sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的
* bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
* 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
*/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果是原型不应该在初始化的时候创建,在这里直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取parentBeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 将别名解析成真正的beanName
String nameToLookup = originalBeanName(name);
// 如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
// 尝试在parentBeanFactory中获取bean对象实例
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// 添加到alreadyCreated set集合当中,表示他已经创建过一次,做标记
markBeanAsCreated(beanName);
}
try {
// 根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查MergedBeanDefinition
checkMergedBeanDefinition(mbd, beanName, args);
// 拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 遍历当前bean依赖的bean名称集合
for (String dep : dependsOn) {
// 检查dep是否依赖于beanName,即检查是否存在循环依赖
if (isDependent(beanName, dep)) {
// 如果是循环依赖则抛异常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 将dep和beanName的依赖关系注册到缓存中
registerDependentBean(dep, beanName);
try {
// 获取dep对应的bean实例,如果dep还没有创建bean实例,则创建dep的bean实例
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// bean 的实例化
if (mbd.isSingleton()) {
// scope为 singleton 的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建Bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// 返回beanName对应的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// scope为 prototype 的bean创建
Object prototypeInstance = null;
try {
// 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
// 创建Bean实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
// 返回beanName对应的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 既不是单例也不是原型的 bean创建,可能是 request之类的
// 根据scopeName,从缓存拿到scope实例
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 {
// 既不是单例也不是原型的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
Object scopedInstance = scope.get(beanName, () -> {
// 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
beforePrototypeCreation(beanName);
try {
// 创建bean实例
return createBean(beanName, mbd, args);
}
finally {
// 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
afterPrototypeCreation(beanName);
}
});
// 返回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) {
// 如果创建bean实例过程中出现异常,则将beanName从alreadyCreated缓存中移除
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 检查所需类型是否与实际的bean对象的类型匹配
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 类型不对,则尝试转换bean类型
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
注意下面的代码,第一次(启动初始化 IOC
容器时 )sharedInstance
肯定为 null
// 先从缓存中获取,因为在容器初始化的时候或者其他地方调用过getBean,已经完成了初始化
Object sharedInstance = getSingleton(beanName);
3.由于 userServiceImpl(原型 bean)
是单例的,所以我们重点关注:
// bean 的实例化
if (mbd.isSingleton()) {
// scope为 singleton 的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建Bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// 返回beanName对应的实例对象
// 这里主要处理实现了FactoryBean的情况,需要调用重写的getObject()方法来获取实际的Bean实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
4.在这里使用 idea
条件断点进行代码调试,在下面这行打断点
sharedInstance = getSingleton(beanName, () -> {
进入 getSingleton
方法如下图:
5.重新打条件断点,进入 singletonFactory.getObject()
方法
6.来到 AbstractAutowireCapableBeanFactory
的 createBean
方法
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
// 确保对应BeanClass完成解析,具体表现是进行了ClassLoder.loadClass或Class.forName完成了类加载
resolveBeanClass(mbd, beanName);
try {
// 准备方法覆盖,主要为lookup-method,replace-method等配置准备
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 供特定后置处理器拓展,如果直接生成了一个Bean,就直接返回不走正常创建流程。
// 具体逻辑是判断当前Spring容器是否注册了实现了InstantiationAwareBeanPostProcessor接口的后置处理器
// 如果有,则依次调用其中的applyBeanPostProcessorsBeforeInstantiation方法,如果中间任意一个方法返回不为null,直接结束调用。
// 然后依次所有注册的BeanPostProcessor的postProcessAfterInitialization方法(同样如果任意一次返回不为null,即终止调用。
Object bean = resolveBeforeInstantiation(beanName, mbd);
// 如果不为空,说明提前生成了实例,直接返回
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
// 具体创建Bean逻辑
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
断点调试发现,下面会产生代理对象,继续追踪
// 具体创建Bean逻辑
Object beanInstance = doCreateBean(beanName, mbd, args);
7.来到了 AbstractAutowireCapableBeanFactory
的 doCreateBean
方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// BeanWrapper封装了具体的Bean实例,然后可以很方便地通过调用getPropertyValue和setPropertyValue等方法反射读写Bean的具体属性
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 先尝试从缓存中取
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 调用构造方法创建一个空实例对象,并用BeanWrapper进行包装
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 获取所有的后置处理器,如果后置处理器实现了MergedBeanDefinitionPostProcessor接口,则一次调用其postProcessMergedBeanDefinition方法
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;
}
}
// 如果满足循环依赖缓存条件,先缓存具体对象
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
/**
* 循环依赖处理逻辑:将已完成实例化,但是未完成属性赋值和相关的初始化的一个不完整的 bean 添加到三级缓存 singletonFactories 中
* 具体内部会遍历后置处理器,判断是否有SmartInstantiationAwareBeanPostProcessor的实现类,然后调用里面getEarlyBeanReference覆盖当前Bean
* 默认不做任何操作返回当前Bean,作为拓展,这里比如可以供AOP来创建代理类
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 开始对Bean实例进行初始化
Object exposedObject = bean;
try {
// 对bean进行属性填充,在这里面完成依赖注入的相关内容
populateBean(beanName, mbd, instanceWrapper);
// 完成属性依赖注入后,进一步初始化Bean
// 具体进行了以下操作:
// 1.若实现了BeanNameAware, BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
// 2.遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
// 3.如果实现了initialzingBean,调用实现的 afterPropertiesSet()
// 4.如果配置了init-mothod,调用相应的init方法
// 5.遍历后置处理器,调用实现的postProcessAfterInitialization
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.");
}
}
}
}
// 如果实现了Disposable接口,会在这里进行注册,最后在销毁的时候调用相应的destroy方法
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
8.在 doCreateBean
方法中会产生代理对象的代码(注意:代理对象的产生是在实例化 bean
和 bean
的属性填充之后进行的):
exposedObject = initializeBean(beanName, exposedObject, mbd);
doCreateBean(beanName, mbd, args)
的主要方法流程:
createBeanInstance(beanName, mbd, args)
:实例化bean
,调用对象的构造方法实例化对象addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName,mbd, bean))
:将已完成实例化,但是未完成属性赋值和相关的初始化的一个不完整的bean
添加到三级缓存singletonFactories
中populateBean(beanName, mbd, instanceWrapper)
:对bean
进行属性填充initializeBean(beanName, exposedObject, mbd)
:完成属性依赖注入后,进一步初始化bean
,在此过程中产生代理对象
9.进入 AbstractAutowireCapableBeanFactory
的 initializeBean
方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 第一步:先执行所有的AwareMethods
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 如果实现了Aware接口,就对该bean进行一些设置
// 比如实现了BeanNameAware接口,那么对其bean的属性beanName上设置对应的beanName
// 如果实现了BeanFactoryAware接口,那么对其beanFactory属性设置上创建该bean使用的bean工厂
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执行所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器方法
// 规则:只要谁反悔了null,后面的就都不要执行了
// 这里面实现postProcessBeforeInitialization 的处理器就很多了,有很多对Aware进行了扩展的
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 如果bean实现了InitializingBean或者用户自定义的init方法方法,那么调用这些初始化方法对bean的属性进行一些个性化设置
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()) {
// 执行后置处理器的postProcessAfterInitialization方法。AOP的原理和实现就在其中
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
9.1initializeBean
方法流程步骤
- 调用各类感知
Aware
接口 - 执行
applyBeanPostProcessorsBeforeInitialization
初始化前的处置操作 - 调用
InitializingBean
接口初始化 (如果配置了method-init
,则调用其方法初始化 ) - 调用
applyBeanPostProcessorsAfterInitialization
初始化之后的处置操作,AOP
的原理和实现就在其中
代理对象产生主要流程步骤小结
- 在
IOC
容器启动初始化时,首先会去一级缓存singletonObjects
中去获取(肯定没有) - 在根据当前
bean
的具体作用域,去初始化bean
- 在做完
bean
的一些校验之后,会调用createBeanInstance
去实例化bean
- 如果存在
bean
的循环依赖的情况,会将当前已实例化的bean put
进三级缓存singletonFactories
中 - 接着会进行
bean
的相关属性填充,注意此时还并没有产生代理对象 - 再接着会进行
bean
的初始化操作,调用initializeBean
方法 - 后续更新查看