创建代理对象
@EnableAspectJAutoProxy
如果需要开启aop功能,那么通常都在主配置类添加 @EnableAspectJAutoProxy
注解,这个注解会为我们在容器中导入一个 AspectJAutoProxyRegistrar
组件。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
AspectJAutoProxyRegistrar
实现了ImportBeanDefinitionRegistrar
接口,它在创建容器 refresh
方法中的invokeBeanFactoryPostProcessors
(执行BeanFactory后置处理器)方法中执行类内的registerBeanDefinitions
方法,即向容器注册 AnnotationAwareAspectJAutoProxyCreator
组件。
AnnotationAwareAspectJAutoProxyCreator
继承体系
AnnotationAwareAspectJAutoProxyCreator
extends AspectJAwareAdvisorAutoProxyCreator
extends AbstractAdvisorAutoProxyCreator
extends AbstractAutoProxyCreator
extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor,BeanFactoryAware
extends InstantiationAwareBeanPostProcessor,Aware
extends BeanPostProcessor
由继承体系,可以知道的是 AnnotationAwareAspectJAutoProxyCreator
是一个bean后置处理器,能在Bean初始化前后对Bean进行相应的处理。
Spring创建bean,在初始化阶段,也就是在执行下面这个代码时
exposedObject = initializeBean(beanName, exposedObject, mbd);
在bean执行完 invokeInitMethods
方法后,也就是初始化后,会调用所有后置处理器的 postProcessAfterInitialization
方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
@Override
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;
}
因为AnnotationAwareAspectJAutoProxyCreator
也是BeanPostProcessor
类型,也会执行方法;并且 AnnotationAwareAspectJAutoProxyCreator
的postProcessAfterInitialization
方法会调用wrapIfNecessary
方法。
wrapIfNecessary
//该方法在AbstractAutoProxyCreator类中
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;
}
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;
}
- 该方法首先判断bean对象是否已经是增强bean,如果是,就直接返回;
- 判断该bean是否不需要增强,如
Advice
,Pointcut
,Advisor
,AopInfrastructureBean
类型的bean就不需要增强,不需要增强,直接返回;advisedBeans
用来保存bean是否需要增强; - 获取该类可以增强的
Advisor
; - 调用
createProxy
方法,创建代理对象;
createProxy
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);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
- 创建
ProxyFactory
,代理对象就是由它创建的; - 将
specificInterceptors
中所有的增强器封装为Advisor
; - 在
ProxyFactory
中添加advisors
属性; - 调用
proxyFactory.getProxy
创建代理对象,该方法最后会调用DefaultAopProxyFactory
的createAopProxy
方法
createAopProxy
//该方法在DefaultAopProxyFactory中
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);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
- 首先进行了条件判断,具体见下
config.isOptimize()
:判断通过CGLIB创建的代理是否使用了优化策略。该条件取值于ProxyConfig
类optimize
属性。此属性标记是否对代理进行优化。启动优化意味着直接优先采用CGLIB代理,默认值为false。config.isProxyTargetClass()
:是否配置了proxy-target-class
为true。该条件取值于ProxyConfig
类的proxyTargetClass
属性。此属性标记是否直接对目标类进行代理,而不是通过接口产生代理。hasNoUserSuppliedProxyInterfaces(config)
:是否不存在代理接口。
如果这些条件有一个为true,就进一步判断,如果都为false,就采用JDK代理方式。
targetClass.isInterface()
:用来判断目标对象是否为接口。Proxy.isProxyClass(targetClass)
:目标类是否是已代理对象
如果满足以上两个要求的其中一个就采用JDK代理方式;都不满足采用CGLIB方式。
总结一下:如果目标类没有接口实现且本身不是接口或已代理对象,就采用CGLIB动态代理,其他情况都采用JDK动态代理。可以通过proxy-target-class
设置是否使用CGLIB代理。
这里返回了一个包装对象,其中有目标对象和所有可以使用的增强器advisor。
getProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
...
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure 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);
// Generate the proxy class and create a proxy instance.
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);
}
}
- 创建
Enhancer
对象,并进行相关设置; - 将包装类的
advisor
包装为拦截器; - 根据
interceptor
数组和enhancer
动态代理创建了一个代理实例(createProxyClassAndInstance
方法中);
此时,代理对象就创建完成了,其中代理对象中有拦截器。
动态代理创建对象总结
aop创建代理对象的关键在于AnnotationAwareAspectJAutoProxyCreator
这个后置处理器,在对象初始化完全后会调用其初始化后置方法对bean进行增强;增强主要包括获取相应的advisor
并将其包装为一个ProxyFactory
对象,然后根据这个对象进行动态代理,并在代理对象中设置相应的拦截器(advisor
包装后的对象interceptor
)。
代理对象方法的执行
在执行目标方法时,会被代理器中的拦截器DynamicAdvisedInterceptor
拦截,执行其intercept
方法。
intercept方法
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
...
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
...
}
- 获取源对象和拦截器链;
- 如果拦截器链长度为空,就反射调用源方法,如果不为空,执行相应的拦截器链;
- 获取返回值;
proceed方法
proceed是拦截方法生效的关键
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
currentInterceptorIndex
初始值为-1
- 第一个
if
判断拦截器链的长度是否为0,如果为0,就反射执行目标方法; - 获取下标为0的相应拦截器(
ExposeInvocationIntecerptor
),执行它的invoke方法
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
这里的invocation
是一个ThreadLocal
,也就是用来存储本线程的变量;
invocation.set(mi);
在threadLocal
设置ReflectiveMethodInvocation
对象,key为ExposeInvocationInterceptor
,value为ReflectiveMethodInvocation
。
再次调用ReflectiveMethodInvocation
的proceed
方法,然后依次调用AspectJAfterThrowingAdvice
,AfterReturningAdviceInterceptor
,AspectJAfterAdvice
,MethodBeforeAdviceInterceptor
的invoke
方法,其中都调用了ReflectiveMethodInvocation
的proceed
方法。
这里有点像DFS(深度遍历),具体见下图
总结
代理方法的执行主要包括获取拦截方法和目标方法,然后采用递归的方式后续遍历依次调用拦截器的invoke方法,然后在后续操作中执行相应的方法。