一:从bean的生命周期四个阶段开始说起。
先附上源码:
// 忽略了无关代码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 实例化阶段!
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 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);
}
}
第一阶段? createBeanInstance()方法实例化bean?
顺便提一下 为了解决循环依赖问题向缓存暴露bean工厂?
第二阶段??populateBean() 属性注入
第三阶段??initializeBean() 方法 进入初始化阶段
第四阶段? 销毁
二:初始化阶段到底都干了些什么?AOP发生在哪里?
先说答案:
????????初始化阶段执行Aware接口 和 后置处理器方法? 执行初始化方法
? ? ? ? AOP发生在初始化方法执行后
附上initializeBean()源码
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 1: 执行Aware接口方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2: 剩余的Aware接口方法 + 后置处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3: 初始化方法
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()) {
// 后置处理器(在这里完成AOP代理)
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
第一步?执行部分Aware接口 ?
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
实现了BeanNameAware BeanClassLoaderAware BeanFactoryAware的bean会执行 ,这三个接口分别会获得bean的name、加载器、工厂
第二步?applyBeanPostProcessorBeforeInitialization()方法?
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
就是循环调用后置处理器的postProcessBeforeInitialization()方法。执行剩下的Aware接口 如ApplicationContextAware(可以让我们拿到整个容器),它会被一个专门的后置处理器ApplicationContextAwareProcessor处理 。以及对 @PostConstructor 和 @PreDestroy注解的处理。这两个注解会被CommonAnnotationBeanPostProcessor这个后置处理器处理 (@PostConstructor注解 : 修饰一个非静态的void方法 该方法会在服务器加载Servlet时运行 且只会被服务器执行一次)?
第三步:?invokeInitMethods() 初始化方法执行
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 是否实现了 InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
// 调用afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 调用afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
?对实现了InitialzingBean接口的Bean先调用接口中的afterPropertiesSet()方法 ?之后再判断是否在Xml的Bean标签中提供了init-method属性
第四步?applyBeanPostProcessorsAfterInitialization() 后置处理器的方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
比如完成AOP的代理 ?@EnableAspectJAutoProxy注解实际上就是向容器中注册了一个AnnotationAwareAspectJAutoProxyCreator,这个类本身就是一个后置处理器,AOP代理就是由它在这一步完成的。 ?
三:和AOP相关的后置处理器具体做了什么呢?
就是执行父类AbstractAutoProxyCreator的postProcessAfterInitialization()方法
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;
}
//省略了部分代码
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// Create proxy if we have advice.
// 获取可以应用到这个Bean上的通知
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果存在通知的话,说明需要被代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//重点在这,创建代理,实际上底层就是new了一个ProxyFactory来创建代理的
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) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
return proxyFactory.getProxy(getProxyClassLoader());
}
getProxy()
?这里有Java动态代理和Cglib代理两种不同的实现方式。我们主要看JdkDynamicAopProxy。
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// proxiedInterfaces是所有需要实现的接口
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
proxiedInterfaces是JdkDynamicAopProxy 的私有属性
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
private final Class<?>[] proxiedInterfaces;
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
}
通过completeProxiedInterfaces()方法获取需要实现的接口
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
// 第一步:获取在配置中指定的需要实现的接口
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
// 第二步:如果没有指定需要实现的接口,但是需要代理的目标类本身就是一个接口
// 那么将其添加到代理类需要实现的接口的集合中
// 如果目标类本身不是一个接口,但是是经过jdk代理后的一个类
// 那么获取这个代理后的类所有实现的接口,并添加到需要实现的接口集合中
if (specifiedInterfaces.length == 0) {
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null) {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
// 第三步:为代理类添加三个默认需要实现的接口,分别是
// 1.SpringProxy,一个标记接口,代表这个类是通过Spring的AOP代理生成的
// 2.Advised,提供了管理通知的方法
// 3.DecoratingProxy,用户获取到真实的目标对象
// 这个真实对象指的是在嵌套代理的情况下会获取到最终的目标对象
// 而不是指返回这个ProxyFactory的target
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
}
if (addAdvised) {
nonUserIfcCount++;
}
if (addDecoratingProxy) {
nonUserIfcCount++;
}
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}
invoke()?
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 首先处理的是hashCode跟equals方法
// 如果接口中没有定义这两个方法,那么会调用本类中定义的equals方法
// 前面我们也说过了,只有当两个类的目标对象,通知以及实现的接口都相等的情况下
// equals才会返回true
// 如果接口中定义了这两个方法,那么最终会调用目标对象中的方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
// 也就是说我们调用的是DecoratingProxy这个接口中的方法
// 这个接口中只定义了一个getDecoratedClass方法,用于获取到
// 最终的目标对象,在方法实现中会通过一个while循环来不断接近
// 最终的目标对象,直到得到的目标对象不是一个被代理的对象才会返回
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// 说明调用的是Advised接口中的方法,这里只是单纯的进行反射调用
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 说明需要将代理类暴露到线程上下文中
// 调用AopContext.setCurrentProxy方法将其放入到一个threadLocal中
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 接下来就是真正的执行代理逻辑了
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 先获取整个拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果没有进行拦截,直接反射调用方法
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
// 否则开始执行整个链条
else {
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
// 这里是处理一种特殊情况,就是当执行的方法返回值为this的情况
// 这种情况下,需要返回当前的代理对象而不是目标对象
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
核心就是?
获取整个拦截器链 然后在在拦截器链上执行方法
如果还想深入研究?
附上链接?Spring中AOP相关的API及源码解析,原来AOP是这样子的_程序员DMZ的博客-CSDN博客
? 文章参考:Spring中AOP相关的API及源码解析,原来AOP是这样子的_程序员DMZ的博客-CSDN博客Spring中AOP相关的API及源码解析本系列文章:读源码,我们可以从第一行读起你知道Spring是怎么解析配置类的吗?配置类为什么要添加@Configuration注解?谈谈Spring中的对象跟Bean,你知道Spring怎么创建对象的吗?这篇文章,我们来谈一谈Spring中的属性注入 推荐阅读:Spring官网阅读 | 总结篇Spring杂谈本系列文章将会带你一行行的将Spring的源码吃透,推荐阅读的文章是阅读源码的基础!因为本文会涉及到动态代理的相关内容,如果对动态代理不https://blog.csdn.net/qq_41907991/article/details/107089754Spring中Bean的生命周期https://www.cychee.cn/archives/spring-zhong-bean-de-sheng-ming-zhou-qiSpring中AOP相关的API及源码解析,原来AOP是这样子的_程序员DMZ的博客-CSDN博客你知道Spring是怎么将AOP应用到Bean的生命周期中的吗?_程序员DMZ的博客-CSDN博客聊一聊Spring是怎么将AOP应用到Bean的生命周期中的?本系列文章:听说你还没学Spring就被源码编译劝退了?30+张图带你玩转Spring编译读源码,我们可以从第一行读起你知道Spring是怎么解析配置类的吗?配置类为什么要添加@Configuration注解?谈谈Spring中的对象跟Bean,你知道Spring怎么创建对象的吗?这篇文章,我们来谈一谈Spring中的属性注入 Spring中AOP相关的API及源码解析,原来AOP是这样子的推荐阅读:Spring官网阅读 |https://daimingzhi.blog.csdn.net/article/details/107141101
?
|