Spring AOP代理对象创建流程

Spring AOP初始化的起点是在bean初始化流程后置处理中。

/**
* bean的初始化流程
*/
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 {
// 为bean包装相关属性,如名称、类加载器、所属容器等
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用BeanPostProcessor的postProcessBeforeInitialization前置处理方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
// 执行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()) {
// 调用BeanPostProcessor的postProcessAfterInitialization后置处理方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}
applyBeanPostProcessorsAfterInitialization方法调用了BeanPostProcessor的postProcessAfterInitialization后置处理方法

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
// 为Bean添加所有BeanPostProcessor的后置处理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
BeanPostProcessor的bean初始化前置处理和初始化后置处理方法均委派其子类实现,其实现子类有很多,其中创建AOP代理对象的子类是AbstractAutoProxyCreator,它实现了postProcessAfterInitialization方法。

下面具体可以分析一下AbstractAutoProxyCreator类的postProcessAfterInitialization方法。

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
// 根据给定的bean的class和name构建一个key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 如果它适合被代理,则需要封装指定的bean
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
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;
}
// 判断是否是基础设施类,或者是否配置了无需自动代理。如果是,缓存key并直接返回
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;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {

......

return proxyFactory.getProxy(getProxyClassLoader());
}


通过上图可以看到,创建代理对象Spring提供了两种方式,JDK动态代理和Cglib AOP代理。

进入createAopProxy()方法,发现这个方法最终在DefaultAopProxyFactory类中被实现。

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// isOptimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略
// isProxyTargetClass:为true时,目标类本身被代理而不是目标类的接口,即使用CGLIB创建代理
// hasNoUserSuppliedProxyInterfaces:是否存在代理接口
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.");
}
// 如果是接口或是一个代理对象就要jdk动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
如果目标对象实现了接口,默认情况下会采用JDK动态代理,但也可以通过配置(proxy-target-class=true)强制使用CGLIB。

如果目标对象没有实现接口,必须采用CGLIB库。

JdkDynamicAopProxy类实现了InvocationHandler接口,我们知道InvocationHandler是JDK动态代理的核心,生成的代理对象的方法调用都会委派到invoke()方法中。

JdkDynamicAopProxy的invoke()方法的核心逻辑为:

先获取应用到目标方法上的拦截器链(Interceptor Chain),如果有拦截器则应用拦截器(before、after、afterReturning等),并执行连接点(JoinPoint)。如果没有拦截器,则直接反射执行连接点。

JDK动态代理与CGLIB的区别:

JDK动态代理只能对实现了接口的类生成代理,不能针对类。

CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,所以该类和方法要保证可以被继承与覆盖。
————————————————
版权声明:本文为CSDN博主「KeepMoving++」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011212394/java/article/details/101795460

猜你喜欢

转载自www.cnblogs.com/sidesky/p/12718658.html