上文(链接地址:)我们详细讲到了找根据Advice和Pointcu找切面(Adviosr)的过程,现在,切面找到了,接下来就是生成代理和调用增强逻辑。
目录
1. 生成代理
进入AOP的入口方法wrapIfNecessary():
所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 如果是false就直接返回
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.
// 找切面的过程(判断当前实例化的bean是否有切面,如果有则将切面返回)*****
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果有切面,则生成bean的代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理,把被代理对象bean的实例封装到SingletonTargetSource中,生成当前实例化bean的代理对象*****
// 传入的bean是被代理实例,SingletonTargetSource持有了被代理实例的引用(一级缓存单例池中存的就是代理对象)
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
// 将代理对象返回
return proxy;
}
// 没有代理的情况,就是false
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
我们着重看Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
这行代码中,SingletonTargetSource持有了原始对象的引用。我们看一下SingletonTargetSource类的组成:
public class SingletonTargetSource implements TargetSource, Serializable {
/** use serialVersionUID from Spring 1.2 for interoperability. */
private static final long serialVersionUID = 9031246629662423738L;
/** Target cached and invoked using reflection. */
private final Object target;
@Override
public Class<?> getTargetClass() {
return this.target.getClass();
}
@Override
public Object getTarget() {
return this.target;
}
----省略无关代码----
在我们日常的AOP中,被代理对象就是Bean对象,是由BeanFactory给我们创建出来的,但是Spring AOP中提供了TargetSource机制,可以用来自定义逻辑来创建被代理对象。
JDK中实现动态代理是实现InvocationHandler接口,但Spring却是实现TargetSource接口, SingletonTargetSource 类实现了TargetSource接口。里面有个target属性,它是Object类型,表示目标对象(被代理对象),TargetSource表示被代理对象的来源。
比如@Lazy注解,当加在属性上时,会产生一个代理对象赋值给这个属性,产生代理对象的代码为:
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final
@Nullable String beanName) {
BeanFactory beanFactory = getBeanFactory();
Assert.state(beanFactory instanceof DefaultListableBeanFactory,
"BeanFactory needs to be a DefaultListableBeanFactory");
final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
TargetSource ts = new TargetSource() {
@Override
public Class<?> getTargetClass() {
return descriptor.getDependencyType();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public Object getTarget() {
Set<String> autowiredBeanNames = (beanName != null ? new LinkedHashSet<>
(1) : null);
Object target = dlbf.doResolveDependency(descriptor, beanName,
autowiredBeanNames, null);
if (target == null) {
Class<?> type = getTargetClass();
if (Map.class == type) {
return Collections.emptyMap();
}
else if (List.class == type) {
return Collections.emptyList();
}
else if (Set.class == type || Collection.class == type) {
return Collections.emptySet();
}
throw new
NoSuchBeanDefinitionException(descriptor.getResolvableType(),
"Optional dependency not present for lazy injection point");
}
if (autowiredBeanNames != null) {
for (String autowiredBeanName : autowiredBeanNames) {
if (dlbf.containsBean(autowiredBeanName)) {
dlbf.registerDependentBean(autowiredBeanName, beanName);
}
}
}
return target;
}
@Override
public void releaseTarget(Object target) {
}
};
ProxyFactory pf = new ProxyFactory();
pf.setTargetSource(ts);
Class<?> dependencyType = descriptor.getDependencyType();
if (dependencyType.isInterface()) {
pf.addInterface(dependencyType);
}
return pf.getProxy(dlbf.getBeanClassLoader());
}
这段代码就利用了ProxyFactory生成代理对象,以及使用了TargetSource,当代理对象在执行某个方法时,调用TargetSource的getTarget()方法它会根据属性在Bean工厂找到对应的对象(byType、byName),得到被代理对象,然后调用被代理对象的方法。
接下来,进入核心方法createProxy():
所属类:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
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();
// 把AnnotationAwareAspectJAutoProxyCreator中的proxyTargetClass、exposeProxy等属性复制到proxyFactory中
// this就是AnnotationAwareAspectJAutoProxyCreator入口类,(proxyTargetClass设置是JDK(默认false)还是CGLIB代理,exposeProxy设置代理对象是否放到threadLocal)
proxyFactory.copyFrom(this);
// 判断是否有接口,如果没有接口,即使设置为JDK,也会使用CGLIB的动态代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 根据之前找到的切面(specificInterceptors)构建Advisor**
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 把Advisor加入到代理工厂
// 在这里会判断advisors是否存在IntroductionAdvisor,如果存在则把对应的interface添加到proxyFactory中去
proxyFactory.addAdvisors(advisors);
// 把targetSource(就是传进来的SingletonTargetSource)加入到代理工厂
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
// freezeProxy这个变量在使用JDK或CGLIB起作用
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 获取代理对象****
return proxyFactory.getProxy(getProxyClassLoader());
}
在这里我提一下,ProxyFactory是Spring对JDK和CGLIB两种动态代理技术的封装,表示是创建代理对象的一个工厂,使用起来会比上面的更加方便,例如:
UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
});
UserInterface userService = (UserInterface) proxyFactory.getProxy();
userService.test();
通过ProxyFactory,可以不用关心到底是用cglib还是jdk动态代理,ProxyFactory会帮我们去判断,如果UserService实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接
口,就会用cglib技术,上面的代码,就是由于UserService实现了UserInterface接口,所以最后产生的代理对象是UserInterface类型。
在createProxy()方法最后一行,进入getProxy()方法:
所属类:org.springframework.aop.framework.ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
// createAopProxy()创建代理方法--->
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// createAopProxy()创建代理对象(JdkDynamicAopProxy或ObjenesisCglibAopProxy)
return getAopProxyFactory().createAopProxy(this);
}
进入createAopProxy()方法
所属类:org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
/**
* 如果不是在graalvm虚拟机上运行,则采用JDK动态代理;
* 如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk效率高;
* 或者isTargetClass(表示代理对象是否为类)为true、或者被代理对象没有实现接口、或者只实现了SpringProxy接口,则采用cglib动态代理;
* 如果被代理类是接口,或者被代理类已经是JDK动态代理,则只能用JDK动态代理。
*/
if (!IN_NATIVE_IMAGE &&
(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);
}
}
需要注意的是ProxyFactory、创建出来的代理对象JdkDynamicAopProxy、当前实例化的Bean,这三个是一一对应的。
回到getProxy()方法,以JDK的动态代理为例,进入JdkDynamicAopProxy的getProxy()方法:
@Override
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);
// 创建代理实例(classLoader为类加载器;proxiedInterfaces为接口;this实现了InvocationHandler接口,就是JdkDynamicAopProxy)
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
返回创建好的代理实例,到此,代理就生成了,大致的过程就是:
源对象——代理对象——获取目标对象(target)= 源对象
2. 执行代理方法
(1) JDK代理
在调用被代理对象的方法时,就会进入JdkDynamicAopProxy的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 {
// 如果接口中没有定义equals()方法,则直接调用,equals()和hashCode()方法不走代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
// 得到代理对象的类型,而不是所实现的接口
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
// 也是直接调用Advised接口中的方法,不走代理逻辑,其实就是利用代理对象获取ProxyFactory中的信息
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 如果ProxyFactory的exposeProxy属性为true,则将代理对象设置到currentProxy这个ThreadLocal中
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 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);
// Get the interception chain for this method.
// 代理对象在执行某个方法时,把方法和被代理的类传进去,然后根据方法筛选出匹配的Advisor,并适配成Interceptor****
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// 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.
// 如果没有Advice,说明没有代理逻辑,则直接执行对应方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
// 把代理类、目标类、方法、参数、代理链传进去,进行代理的增强
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 执行MethodInterceptor代理逻辑*****
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
----省略无关代码----
}
进入getInterceptorsAndDynamicInterceptionAdvice()方法:
所属类:org.springframework.aop.framework.AdvisedSupport
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
// 代理对象在执行某个方法时,会根据当前ProxyFactory中所设置的Advisor根据当前Method再次进行过滤
MethodCacheKey cacheKey = new MethodCacheKey(method);
// 注意这个List,表示的就是Advice链
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
进入getInterceptorsAndDynamicInterceptionAdvice()方法:
所属类:org.springframework.aop.framework.DefaultAdvisorChainFactory
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 从ProxyFactory中拿到所有设置的Advice(添加时被封装成了DefaultPointcutAdvisor),添加的时候会控制顺序
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 先匹配类
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 再匹配方法
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
// 如果匹配则将Advisor封装成MethodInterceptor,当前Advisor中的Advice可能就是MethodBeforeAdvice
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
// 最终,interceptorList中存放的是当前正在执行的Method所匹配的MethodInterceptor,
// 找到Method所匹配的MethodInterceptor后,就会开始调用这些MethodInterceptor,如果是动态的。
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
在这里会通过getClassFilter()匹配类,再通过getMethodMatcher()匹配方法,如果匹配则将Advisor封装成MethodInterceptor数组,当前Advisor中的Advice就是MethodInterceptor,进入getInterceptors()方法:
所属类:org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 将Advice适配成MethodInterceptor
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
我们看一下DefaultAdvisorAdapterRegistry的构造方法,会注册三个适配器:
/**
* Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
*/
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
以MethodBeforeAdviceAdapter为例,看看该类的结构:
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
// 先执行增强方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
}
它实现了MethodInterceptor接口,执行invoke()方法,会先执行增强方法,然后再执行代理链,“火箭传递”过程。同理,再看一下处理异常的适配器类ThrowsAdviceAdapter:
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof ThrowsAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
return new ThrowsAdviceInterceptor(advisor.getAdvice());
}
}
看看它对应的方法拦截器ThrowsAdviceInterceptor类:
public ThrowsAdviceInterceptor(Object throwsAdvice) {
Assert.notNull(throwsAdvice, "Advice must not be null");
this.throwsAdvice = throwsAdvice;
Method[] methods = throwsAdvice.getClass().getMethods();
for (Method method : methods) {
// 方法名必须是afterThrowing,参数个数1个或4个
// 1个参数:public void afterThrowing(Exception ex)
// 4个参数:public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
if (method.getName().equals(AFTER_THROWING) &&
(method.getParameterCount() == 1 || method.getParameterCount() == 4)) {
Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1];
if (Throwable.class.isAssignableFrom(throwableParam)) {
// An exception handler to register...
this.exceptionHandlerMap.put(throwableParam, method);
if (logger.isDebugEnabled()) {
logger.debug("Found exception handler method on throws advice: " + method);
}
}
}
}
if (this.exceptionHandlerMap.isEmpty()) {
throw new IllegalArgumentException(
"At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
}
}
a. 链式调用
将前面收集好的切面进行循环执行,就是链式调用过程,主要看proceed()方法,匹配成功才执行增强逻辑invoke()方法,如果不匹配则递归调用,执行下一个MethodInterceptor。
所属类:org.springframework.aop.framework.ReflectiveMethodInvocation
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// currentInterceptorIndex初始值为-1,每调用一个interceptor会+1,当调用最后一个interceptor后就会执行被代理方法invokeJoinpoint()
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// interceptorsAndDynamicMethodMatchers就是拦截器链,通过currentInterceptorIndex循环执行增强方法
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 如果当前interceptor是interceptorOrInterceptionAdvice,则先匹配,匹配成功后再调用该interceptor
// 如果没有匹配,则递归调用proceed()方法,调用下一个interceptor
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
// 只有MethodMather的isRuntime()返回true,它的类型才是InterceptorAndDynamicMethodMatcher
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
// 动态匹配,匹配方法、类名和入参,匹配成功才执行增强逻辑invoke()方法
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.
// 如果不匹配则递归调用,执行下一个MethodInterceptor
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 直接调用那三种MethodInterceptor(ThrowsAdviceInterceptor、MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor),传入this,在内部会再次执行proceed()方法进行递归
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
b. @Before增强
@Before注解的方法,invoke()会执行MethodBeforeAdviceInterceptor.invoke()方法:
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 调用完before()方法的增强之后,继续执行后面的增强,会再次调用ReflectiveMethodInvocation.proceed()方法
return mi.proceed();
}
所属类:org.springframework.aop.aspectj.AspectJMethodBeforeAdvice
// 代理对象执行时就会执行该方法
@Override
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
通过invokeAdviceMethod()方法,最终会调用到AspectJMethodBeforeAdvice.invokeAdviceMethodWithGivenArgs()方法:
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
// aspectJAdviceMethod是@Before修饰的方法
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
// 反射调用aspectJAdviceMethod方法
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection
// this.aspectInstanceFactory.getAspectInstance()指切面Bean的实例,actualArgs为方法参数,执行对应方法
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
----省略无关代码----
这样就调用到了@Before注解对应的方法,调用完before的增强之后,继续执行后面的增强,会再次调用ReflectiveMethodInvocation.proceed()方法,把接力棒传下去。看一下调用被代理方法的逻辑invokeJoinpoint():
所属类:org.springframework.aop.framework.ReflectiveMethodInvocation
protected Object invokeJoinpoint() throws Throwable {
// 反射调用被代理方法,入参分别为目标对象,方法、参数
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
c. @After增强
@After注解的增强器AspectJAfterAdvice :
public class AspectJAfterAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
public AspectJAfterAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
先执行目标方法,增强逻辑是在finally中执行的。
d. @AfterReturning增强
@AfterReturning的增强器AfterReturningAdviceInterceptor,先进行火炬传递,可能是其他增强方法,如果调用链执行完,就会调到被代理方法,然后才能拿返回值。
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
private final AfterReturningAdvice advice;
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 先调用被代理方法
Object retVal = mi.proceed();
// 拿到返回值后进行反射调用
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
使用场景为:
@AfterReturning(value = "pc1()", returning = "retVal")
public void afterReturning(JoinPoint joinPoint, Object retVal) {
System.out.println("==============AspectAnnotation.afterReturning后置通知 拿返回值=========" + retVal);
}
e. @AfterThrowing增强
@AfterThrowing对应的拦截器为AspectJAfterThrowingAdvice,当被代理方法有异常时才会执行被代理方法。
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {
public AspectJAfterThrowingAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
应用举例:
@AfterThrowing(value = "pc1()", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Throwable e) {
System.out.println("AspectAnnotation.afterThrowing异常通知 拿异常=========" + e);
}
f. @Around增强
@Around注解对应的拦截器类AspectJAroundAdvice,业务中我们一般使用@Around的增强较多,既能前置,又能后置,也能拿返回值,也能处理异常。
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
public AspectJAroundAdvice(
Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJAroundAdviceMethod, pointcut, aif);
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
return invokeAdviceMethod(pjp, jpm, null, null);
}
使用实例:
@Around(value = "pc1()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("==============AspectAnnotation.around前置通知=========");
Object result = joinPoint.proceed();
System.out.println("==============AspectAnnotation.around后置通知=========");
return result;
}
环绕增强跟其他拦截不同的是,火炬传递的动作需要人为去触发,通过Object result = joinPoint.proceed();以保证增强链的不断执行,但前置、后置等增强,只需定义增强逻辑,Spring会帮我们进行增强逻辑的传递。
(2)Cglib代理
看完了JdkDynamicAopProxy的代理,再看看CglibAopProxy类的getProxy(java.lang.ClassLoader)方法:
@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;
// 如果被代理类已经是cglib生成的代理类
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
// 获取真正的被代理类
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 ClassLoaderAwareGeneratorStrategy(classLoader));
// 相当于方法拦截器,获取和被代理类所匹配的Advisor
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
}
进入 getCallbacks()方法:
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
// CGLIB产生的代理对象执行代理逻辑会进入到这里
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
CGLIB产生的代理对象执行代理逻辑会进入到DynamicAdvisedInterceptor类,进去:
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
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 {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 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);
}
// 如果不为空,构造出一个方法调用包装类CglibMethodInvocation
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;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
当调用逻辑进入到这里,会执行intercept()方法,和JDK实现的功能一摸一样~只是代码不同而已。
3. 总结
通过一个流程图来加深本节内容理解:
总结一下代理对象执行过程:
- 在使用ProxyFactory创建代理对象之前,需要ProxyFactory添加Advisor;
- 代理对象在执行某个方法时,会把ProxyFactory中的Advisor拿出来和当前正在执行的方法进行匹配筛选;
- 把和当前方法匹配的Advisor适配成MethodInterceptor;
- 把和当前方法匹配的MethodInterceptor执行链,以及被代理对象、代理对象、代理类、当前Method对象、方法参数封装为MethodInvocation对象;
- 调用MethodInvocation的proceed()方法,开始执行各个MethodInterceptor以及被代理对象的对应方法;
- 按顺序调用每个MethodInterceptor的invoke()方法,并且会把MethodInvocation对象传入invoke()方法;
- 直到执行完最后一个MethodInterceptor,就会调用invokeJoinpoint()方法,从而执行被代理对象的当前方法。
总之,就是某个需要AOP的类通过Pointcut的ClassFilter和MethodMatcher找到所有匹配的Advisor,然后利用ProxyFactory生成代理对象;代理对象执行方法时,根据当前调用的方法,找到与之相匹配的Advisor,执行对应的Advice逻辑。