文章目录
Spring Aop的核心
就是
生成动态代理
和
动态代理织入
,本篇主要讲
Spring Aop动态代理织入
,
Spring Aop生成动态代理
在
Spring Aop生成动态代理博文中
织入的定义
将目标对象中和其他对象连接起来的过程叫做织入
织入的种类
- 编译期织入
执行效率高,不够灵活
- 装载时注入
稍微灵活,可以在JVM装载目标类对象和声明类对象的时候进行合并,执行效率不够高
- 运行时织入(动态代理织入)
最灵活,通过配置文件进行目标类对象和通知进行合并的,效率低
Spring Aop属于运行时织入
,AspectJ采用编译期织入和类装载期织入
Spring Aop在调用调用代理方法时,使用责任链设计模式
来对目标对象和通知对象执行合并,从而达到在程序运行时织入
调用代理方法
invoke(proxy, method, args)
/**
* 也就是当Proxy对象的代理方法被调用时,JdkDynamicAopProxy的的invoke方法作为Proxy对象的回调函数被触发,从而通过invoke的具体实现,来完成对目标对象方法调用的拦截或者说功能的增强工作
* 在Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)生成动态代理对象时,this需要时实现了InvocationHandler接口,并重写invoke()方法,在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 {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
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 {
// 根据proxy(代理对象)、target(目标对象)、method(方法对象)、args(目标对象调用的方法参数)、targetClass(目标对象的Class对象)、chain(拦截器链)来生成拦截器链
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 通过责任链模式来连接拦截器链
retVal = invocation.proceed();
}
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()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
invocation.proceed()
public Object proceed() throws Throwable {
// //从-1开始计数
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 调用目标对象方法
return invokeJoinpoint();
}
// 从拦截器链中获取MethodInterceptor拦截器,然后currentInterceptorIndex并进行++currentInterceptorIndex
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 如果MethodInterceptor拦截器是InterceptorAndDynamicMethodMatcher类型的
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
// 这里每一次都去匹配是否适用于这个目标方法
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// 递归调用,进行下一个拦截器链进行调用
return proceed();
}
}
else {
// 这里this为当前ReflectiveMethodInvocation对象
// 在invoke()方法中也进行递归调用
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
invokeJoinpoint()
/**
* 调用目标对象方法
*/
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
/**
* 调用目标对象方法的真正实现
*/
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
throws Throwable {
// 利用反射来执行目标对象的方法
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
用来处理@Before
、@After
、@AfterRunning
、@AfterThrowing
方法的类都实现了MethodInterceptor接口,重写了invoke()方法,在方法中各自实现了不同的逻辑
@Before的处理类MethodBeforeAdviceInterceptor
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 执行前置通知方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 回调方法,在这里进行调用后面的MethodInvocation拦截器
return mi.proceed();
}
}
@After的处理类AspectJAfterAdvice
public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
// 执行后置通知方法
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
}
@AfterRunning的处理类AfterReturningAdviceInterceptor
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
private final AfterReturningAdvice 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;
}
}
@AfterThrowing的处理类AspectJAfterThrowingAdvice
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
// 执行异常通知方法
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
}