文章目录
前言
Spring 中所谓的Aop 就是为已经存在的bean ,动态的插入一段代理逻辑,从而实现某些指定的方法进行增强。
一、spirng 的aop是什么:
在Spring框架中,Spring AOP 是核心容器的一部分,允许通过代理模式为对象提供横切关系。代理模式允许Spring通过一个代理类来包装用户定义的bean,以便在调用实际bean之前或之后插入附加的行为。
二、spring 中如何使用aop:
2.1 使用 ProxyFactory 生成代理对象
准备代码:
import org.springframework.stereotype.Component;
@Component
public class AspectTestService {
public void test(){
System.out.println("test 方法调用");
}
public void abc(){
System.out.println("abc 方法调用");
}
}
使用 ProxyFactory 进行对象的代理:
package com.example.springdabaihua.aspect.proxy;
import com.example.springdabaihua.aspect.service.AspectTestService;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.*;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import java.lang.reflect.Method;
public class ProxyTestMain {
public static void main(String[] args) {
AspectTestService service = new AspectTestService();
// service.test();
ProxyFactory factory = new ProxyFactory();
factory.setTarget(service);
// 统一设置代理逻辑
factory.addAdvice(new MethodBeforeAdvice() {
// 方法的前置
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("method before");
}
});
factory.addAdvice(new AfterReturningAdvice() {
// 方法调用之后放回之前
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("method after");
}
});
factory.addAdvice(new MethodInterceptor() {
// 方法的环绕
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("method before Interceptor1");
Object proceed = invocation.proceed();
System.out.println("method after Interceptor1");
return proceed;
}
});
factory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("method before Interceptor2");
Object proceed = invocation.proceed();
System.out.println("method after Interceptor2");
return proceed;
}
});
factory.addAdvice(new ThrowsAdvice() {
// @Override
public void afterThrowing( Method method, Object[] args, Object target,RuntimeException ex) {
System.out.println("method error");
}
});
// 对匹配的方法 设置代理逻辑
factory.addAdvisor(new PointcutAdvisor() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
// 匹配的方法
return method.getName().equals("abc");
}
};
}
@Override
public Advice getAdvice() {
return new MethodBeforeAdvice() {
// 代理逻辑
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("method before");
}
};
}
@Override
public boolean isPerInstance() {
return false;
}
});
AspectTestService proxy = (AspectTestService) factory.getProxy();
proxy.test();
proxy.abc();
}
}
通过ProxyFactory,我们可以不再关系到底是用cglib还是jdk动态代理了,ProxyFactory会帮我们去判断,如果AspectTestService实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接口,就会用cglib技术。
2.2 BeanNameAutoProxyCreator 为已经存在的bean 代理:
@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
beanNameAutoProxyCreator.setBeanNames("aspectTestService");
beanNameAutoProxyCreator.setInterceptorNames("testBeforeAdvice","testAroundAdvice");
beanNameAutoProxyCreator.setProxyTargetClass(true);
return beanNameAutoProxyCreator;
}
@Bean
public MethodBeforeAdvice testBeforeAdvice(){
return new MethodBeforeAdvice() {
// 方法的前置
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("method before");
}
};
}
@Bean
public MethodInterceptor testAroundAdvice(){
return new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
};
}
这里我们为已经存在的aspectTestService 增加了两个代理逻辑一个是方法之前之前的before ,一个是 around; 这里增加的Advice 的类型和 使用 ProxyFactory 进行对象的代理 是相同的;这样可以实现为已经存在的bean 进行逻辑的增强了;
2.2 DefaultPointcutAdvisor 为已经存在的bean 中方法进行代理:
首先导入 DefaultAdvisorAutoProxyCreator 让spirng 可以收集我们定义的Advisor:
@Import(DefaultAdvisorAutoProxyCreator.class)
然后设置我们自己的Advisor:
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor() {
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
// 对已经存在的bean 中的abc 方法进行代理
pointcut.addMethodName("abc");
DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
defaultPointcutAdvisor.setPointcut(pointcut);
defaultPointcutAdvisor.setAdvice(new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("method berfore 执行");
}
});
return defaultPointcutAdvisor;
}
三、Spring ProxyFactory 的工作原理:
3.1 ProxyFactory getProxy() 获取代理类:
public Object getProxy() {
// 先创建一个代理 然后获取代理对象
return this.createAopProxy().getProxy();
}
// synchronized 对象锁
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
this.activate();
}
// getAopProxyFactory 确定 使用jdk 还是cglib 代理
return this.getAopProxyFactory().createAopProxy(this);
}
DefaultAopProxyFactory 下 createAopProxy 获取动态代理:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (NativeDetector.inNativeImage() || !config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
// config.isOptimize() 默认false 是否使用优化,因为早期的cglib 效率要高于jdk
// config.isProxyTargetClass() 默认false 代理的是否是一个类 ,false 代表要代理的是一个接口
// true 表示代理类 则使用cglib
// hasNoUserSuppliedProxyInterfaces 是否有添加接口,添加了接口为false ,没有添加接口 true
return new JdkDynamicAopProxy(config);
} else {
//获取被代理的类
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.");
} else {
// 被代理的类是一个接口 或者 产生的代理类,是jdk 的动态代理类,则使用jdk 动态代理
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) && !ClassUtils.isLambdaClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
3.2 jdk 的动态代理:JdkDynamicAopProxy
获取动态代理:
public Object getProxy() {
return this.getProxy(ClassUtils.getDefaultClassLoader());
}
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(this.determineClassLoader(classLoader), this.proxiedInterfaces, this);
}
jdk 动态代理方法的执行:
@Nullable
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;
Object var12;
try {
// 如果是 equals 则不需要代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
Boolean var18 = this.equals(args[0]);
return var18;
}
// 如果是 hashCode 则不需要代理
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
Integer var17 = this.hashCode();
return var17;
}
//
if (method.getDeclaringClass() == DecoratingProxy.class) {
Class var16 = AopProxyUtils.ultimateTargetClass(this.advised);
return var16;
}
Object retVal;
if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
return retVal;
}
// 如果 exposeProxy 是true(默认false) 则暴露代理对象到 线程中,当前线程后续可以直接获取到代理对象
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取被代理对象
target = targetSource.getTarget();
Class<?> targetClass = target != null ? target.getClass() : null;
// 获取 advise 的链路
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
// 没有代理链
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 直接执行被代理对象的方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// 获取到 MethodInvocation 对象,
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);
}
var12 = retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
return var12;
}
advise 链路的获取:getInterceptorsAndDynamicInterceptionAdvice
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
// 先从缓存拿
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = (List)this.methodCache.get(cacheKey);
if (cached == null) {
// 缓存拿不到,则进行获取
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
getInterceptorsAndDynamicInterceptionAdvice:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) {
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 获取添加的advisor
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList(advisors.length);
Class<?> actualClass = targetClass != null ? targetClass : method.getDeclaringClass();
Boolean hasIntroductions = null;
Advisor[] var9 = advisors;
int var10 = advisors.length;
for(int var11 = 0; var11 < var10; ++var11) {
// 遍历每个advisor
Advisor advisor = var9[var11];
if (advisor instanceof PointcutAdvisor) {
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
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// 如果是运行时
MethodInterceptor[] var17 = interceptors;
int var18 = interceptors.length;
for(int var19 = 0; var19 < var18; ++var19) {
MethodInterceptor interceptor = var17[var19];
// 对其进行InterceptorAndDynamicMethodMatcher 包装,
// 在对传入的参数进行匹配
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
} else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
} 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;
}
MethodInterceptor 的对象包装:registry.getInterceptors(advisor);
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList(3);
// 获取 advice
Advice advice = advisor.getAdvice();
// 如果本身就是 MethodInterceptor 则直接添加
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor)advice);
}
// 对 advice 进行3个适配器的匹配:
// MethodBeforeAdviceAdapter/ AfterReturningAdviceAdapter/ThrowsAdviceAdapter
Iterator var4 = this.adapters.iterator();
while(var4.hasNext()) {
AdvisorAdapter adapter = (AdvisorAdapter)var4.next();
if (adapter.supportsAdvice(advice)) {
// 如果适配则调用适配器的getInterceptor 方法获取MethodInterceptor
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
} else {
return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[0]);
}
}
3个适配器:正是因为底层去匹配了这3个适配器,所以我们在代码里才可以对其进行实现
(1) 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;
}
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
// 先调用目标的方法
Object retVal = mi.proceed();
// 在调用 advice 中的 afterReturning 方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}
(2) 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;
}
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
// 先调用 advice 的befor 方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 在调用目标方法
return mi.proceed();
}
}
(3) ThrowsAdviceAdapter:
public ThrowsAdviceInterceptor(Object throwsAdvice) {
Assert.notNull(throwsAdvice, "Advice must not be null");
this.throwsAdvice = throwsAdvice;
Method[] methods = throwsAdvice.getClass().getMethods();
Method[] var3 = methods;
int var4 = methods.length;
// 遍历throwsAdvice 的所有方法
for(int var5 = 0; var5 < var4; ++var5) {
Method method = var3[var5];
if (method.getName().equals("afterThrowing") && (method.getParameterCount() == 1 || method.getParameterCount() == 4)) {
// 获取到异常类型参数
Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1];
if (Throwable.class.isAssignableFrom(throwableParam)) {
// 将异常和 方法 作为 key 和value 放入到map 中
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() + "]");
}
}
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
try {
// 方法调用
return mi.proceed();
} catch (Throwable var4) {
// 如果异常了,则得到改异常对应的方法
Method handlerMethod = this.getExceptionHandler(var4);
if (handlerMethod != null) {
// 方法不为空,则执行方法
this.invokeHandlerMethod(mi, var4, handlerMethod);
}
// 最终抛出异常
throw var4;
}
}
代理逻辑链路的执行:ReflectiveMethodInvocation下 proceed 方法
@Nullable
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 如果没有advise 链路/ 或者advise 链路的方法都执行完了, 则直接调用目标方法
return this.invokeJoinpoint();
} else {
// 进行循环遍历,先取出第一个advise
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 如果是 InterceptorAndDynamicMethodMatcher 对象
// 如果改advise 是runTime 的会对其封装成 InterceptorAndDynamicMethodMatcher
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
// 进行参数匹配,如果匹配则执行改advise 的invoke 方法,否则进行下一次循环
return dm.methodMatcher.matches(this.method, targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
// 调用每个 advise 的invoke 方法 ,每次调用都对currentInterceptorIndex ++
// 从而实现对每个 advise 的invoke 的调用
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
3.3 cglib的动态代理:CglibAopProxy
获取动态代理:
public Object getProxy() {
return this.getProxy((ClassLoader)null);
}
getProxy 获取代理对象:
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 被代理对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
int x;
if (rootClass.getName().contains("$$")) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
Class[] var5 = additionalInterfaces;
int var6 = additionalInterfaces.length;
for(x = 0; x < var6; ++x) {
Class<?> additionalInterface = var5[x];
this.advised.addInterface(additionalInterface);
}
}
this.validateClassIfNecessary(proxySuperClass, classLoader);
// 代理对象
Enhancer enhancer = this.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));
Callback[] callbacks = this.getCallbacks(rootClass);
Class<?>[] types = new Class[callbacks.length];
for(x = 0; x < types.length; ++x) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// 获取代理对象
return this.createProxyClassAndInstance(enhancer, callbacks);
} catch (IllegalArgumentException | CodeGenerationException var9) {
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", var9);
} catch (Throwable var10) {
throw new AopConfigException("Unexpected AOP exception", var10);
}
}
总结:
本文列举了通过 Spring 中的BeanNameAutoProxyCreator ,DefaultPointcutAdvisor 来为bean 进行代理逻辑的实现,并对底层使用的ProxyFactory 工作原理进行介绍。