在之前的通过Spring AOP实现自定义注解一文中,使用切面的方式来对注解方法实现了AOP增强,下面从底层分析一下Spring框架是如何生成AOP代理对象的。
在使用@Aspect注解时,由于beanPostProcessors中包含了AnnotationAwareAspectJAutoProxyCreator,所以对于所有的bean在初始化的时候都会检查是否进行aop代理。在Spring框架中,postProcessAfterInitialization方法用于对所有的已经初始化完成的bean进行二次处理。
AbstractAutoProxyCreator.java
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 检查缓存中是否存在这个bean,如果不存在则进行bean的增强处理,否则直接返回bean
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary()方法用于判断当前的bean是否需要进行AOP代理
AbstractAutoProxyCreator.java
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 如果之前曾经检查过这个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;
}
// 从所有的advisor中进行检索,判断是否有合适的advisor可以进行代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果发现有合适的advisor可以进行代理则生成代理对象
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;
}
// 否则在缓存中记录下当前的bean不需要进行代理,并直接返回bean
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
创造代理对象时使用createProxy()方法
AbstractAutoProxyCreator.java
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);
}
}
// 在这里为bean设置增强的切面
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 首先设置需要被注入的advisor
proxyFactory.addAdvisors(advisors);
// 接着设置被代理的对象
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 通过工厂方法获取代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
proxyFactory的getProxy()方法调用了ProxyCreatorSupport的AopProxy()方法
ProxyCreatorSupport.java
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
在实际的DefaultAopProxyFactory中重写了ProxyCreatorSupport的createAopProxy方法,并最终在这里生成了代理对象,代理对象的生成有两种策略,一种是cglib,一种是jdk动态代理
DefaultAopProxyFactory.java
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);
}
// 如果设置了强制使用cglib代理或者是没有接口则使用cglib
return new ObjenesisCglibAopProxy(config);
}
else {
// 否则使用jdk提供的动态代理
return new JdkDynamicAopProxy(config);
}
}
在上一步返回两个不同的对象后,都会使用getProxy()方法生成真正的代理对象并最为bean放入bean容器中,两种代理对象的不同就体现在这两种不同的getProxy()方法实现,其中cglib使用Enhancer来生成代理对象,jdk使用Proxy来生成。
cglib
public Object getProxy(@Nullable ClassLoader classLoader) {
...
try {
...
// 使用cglib提供的Enhancer类来对目标对象进行代理
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 在这里构建真正的代理对象
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
jdk动态代理
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 调用Proxy生成代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}