本篇文章为你整理了Spring的AOP底层解析(springaop底层实现原理)的详细内容,包含有spring aop底层原理实现流程 springaop底层实现原理 springaop底层实现原理 spring aop原理解析 Spring的AOP底层解析,希望能帮助你了解 Spring的AOP底层解析。
AOP原理的前置知识
(1)动态代理(具体可查看 java的动态代理底层解析 )
动态代理在Spring中的应用:
1.AOP
2.注解@Lazy
(2)Spring中针对动态代理的封装
1.ProxyFactory
(1)介绍
基于两种动态代理技术,在Spring中进行了封装,封装出来的类叫做ProxyFactory,表示是创建代理对象的一个工厂,使用起来会更加方便。
(2)简单使用
通过ProxyFactory,我们可以不再关系到底是用cglib还是jdk动态代理了,ProxyFactory会帮我们去判断,如果UserService实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接口,就会用cglib技术。
UserService userService1 = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(userService1);
proxyFactory.addAdvice(new MethodInterceptor() {
@Nullable
@Override
public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
System.out.println("切面逻辑 before...");
Object result = invocation.proceed(); //执行被代理的方法,用于传递句柄
//invocation.getMethod().invoke(invocation.getThis(), invocation.getArguments()); //执行被代理对象的方法
System.out.println("切面逻辑 after...");
return result;
UserService userService2 = (UserService) proxyFactory.getProxy();
userService2.test();
(3)方法说明
1、setTarget(),创建一个单例的代理对象
2、addAdvice添加代理方法,该方法实现了Advice接口
3、getProxy() 获取代理对象,AOP代理的Bean是通过该方法增强的
(4)Advice的分类
据我们想要对方法增强的话会有以下情况:
1. Before Advice:方法之前执行(对应MethodBeforeAdvice接口)
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method method, Object[] args, @Nullable Object target) throws Throwable;
}
2. After returning advice:方法return后执行 (对应AfterReturningAdvice接口)
public interface AfterReturningAdvice extends AfterAdvice {
void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable;
}
3. After throwing advice:方法抛异常后执行(对应ThrowsAdvice接口)
/**
* 注解上的示例
* pre void afterThrowing([Method, args, target], ThrowableSubclass); /pre
* p Some examples of valid methods would be:
* pre public void afterThrowing(Exception ex) /pre
* pre public void afterThrowing(RemoteException) /pre
* pre public void afterThrowing(Method method, Object[] args, Object target, Exception ex) /pre
* pre public void afterThrowing(Method method, Object[] args, Object target, ServletException ex) /pre
public interface ThrowsAdvice extends AfterAdvice {}
//为什么不定义方法,因为对于异常可以自定义,根据自己定义的不同异常进行捕捉执行拦截方法
4. After (finally) advice:方法执行完finally之后执行,这是最后的,比return更后(对应AfterAdvice接口)
5. Around advice:这是功能最强大的Advice,可以自定义执行顺序(对应MethodInterceptor接口)
/**
* 注解上有着对应的示例
* pre "method "+i.getMethod()+" is called on "+
* i.getThis()+" with args "+i.getArguments());
* Object ret=i.proceed();
* System.out.println("method "+i.getMethod()+" returns "+ret);
* return ret;
* /pre
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
(5)链路形成的原理
1.addAdvice添加代理方法展示(既然有多个,那么调用的时候必然也要都调用)
//这个方法本质上最终是将advisor参数添加到this.advisors属性里面
public void addAdvisor(Advisor advisor) {
int pos = this.advisors.size();
addAdvisor(pos, advisor);
}
2.拦截器的句柄传递(分析invocation.proceed())
//ReflectiveMethodInvocation类#proceed()方法
public Object proceed() throws Throwable {
// currentInterceptorIndex初始值为-1,每调用一个interceptor就会加1,当调用完了最后一个interceptor后就会执行被代理方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
// currentInterceptorIndex初始值为-1,根据下标获取拦截器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 当前interceptor是InterceptorAndDynamicMethodMatcher,则先进行匹配,匹配成功后再调用该interceptor
// 如果没有匹配则递归调用proceed()方法,调用下一个interceptor
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
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 {
// 不匹配则执行下一个MethodInterceptor
return proceed();
else {
// 直接调用MethodInterceptor,传入this,在内部会再次调用proceed()方法进行递归,如:MethodBeforeAdviceInterceptor
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
AopUtils类#invokeJoinpointUsingReflection方法
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable {
try {
ReflectionUtils.makeAccessible(method);
// 执行普通对象的方法,注意和@Configuration产生的代理对象的逻辑区别
return method.invoke(target, args);
catch (InvocationTargetException ex) {...} catch (IllegalArgumentException ex) {...} catch (IllegalAccessException ex) {...}
}
(6)Advisor的理解
1.介绍说明
跟Advice类似的还有一个Advisor的概念,一个Advisor是有一个Pointcut和一个Advice组成的,通过Pointcut可以指定要需要被代理的逻辑,比如一个UserService类中有两个方法,按上面的方法,这两个方法都会被代理,被增强,那么我们现在可以通过Advisor,来控制到具体代理哪一个方法。
2.代码示例(产生的代理对象,只有在执行testAbc这个方法时才会被增强,会执行额外的逻辑,而在执行其他方法时是不会增强的)
public class UserServiceImpl implements UserService {
@Override
public String doSomething0(String param) {
System.out.println("==============doSomething0");
return "doSomething0";
@Override
public String doSomething1(String param) {
System.out.println("==============doSomething1");
return "doSomething1";
@Override
public String doSomething2(String param) {
System.out.println("==============doSomething2");
return "doSomething2";
@Override
public String myMethod(String param) {
System.out.println("==============myMethod");
return "myMethod";
//操作代码
UserService userService1 = new UserServiceImpl();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(userService1);
proxyFactory.addAdvisor(new PointcutAdvisor() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class ? targetClass) {
return method.getName().equals("doSomething1");
@Override
public Advice getAdvice() {
return new MyAroundAdvice();
@Override
public boolean isPerInstance() {
return false;
UserService userService2 = (UserService) proxyFactory.getProxy();
userService2.doSomething0("456");
2.ProxyFactoryBean
(1)介绍
在使用Spring时,我们不会直接去使用ProxyFactory,因为我们希望所产生的代理对象能直接就是Bean能直接从Spring容器中得到代理对象,故使用ProxyFactoryBean。
(2)简单使用
通过这种方法来定义一个Bean,并且是经过了AOP的。但是这种方式只能针对某一个Bean。它是一个FactoryBean,所以利用的就是FactoryBean技术,间接的将类的代理对象作为了Bean。
方法1:
@Bean
public ProxyFactoryBean userService1() {
UserService userService = new UserService();
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setTarget(userService);
proxyFactoryBean.addAdvisor(new PointcutAdvisor() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class ? targetClass) {
return method.getName().equals("doSomething1");
@Override
public Advice getAdvice() {
return new MyAroundAdvice();
@Override
public boolean isPerInstance() {
return false;
return proxyFactoryBean;
}
方法2:
//把某个Advise或Advisor定义成为Bean,然后在ProxyFactoryBean中进行设置
@Bean
public MyAroundAdvice MyAroundAdvise() {
return new MyAroundAdvice();
UserService userService = new UserService();
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setProxyTargetClass(true);
proxyFactoryBean.setTarget(userService);
proxyFactoryBean.setInterceptorNames("myAroundAdvise");
return proxyFactoryBean;
}
3.BeanNameAutoProxyCreator
(1)介绍
根据继承关系可知BeanNameAutoProxyCreator类继承了AbstractAdvisorAutoProxyCreator类(AbstractAutoProxyCreator有个抽象方法getAdvicesAndAdvisorsForBean方法)
该类实现SmartInstantiationAwareBeanPostProcessor接口(该接口继承InstantiationAwareBeanPostProcessor接口【用于实例化的接口】)
ProxyFactoryBean得自己指定被代理的对象,那么我们可以通过BeanNameAutoProxyCreator来通过指定某个bean的名字,来对该bean进行代理。
通过BeanNameAutoProxyCreator可以对批量的Bean进行AOP,并且指定了代理逻辑,指定了一个InterceptorName,也就是一个Advise,前提条件是这个Advise也得是一个Bean,这样Spring才能找到的,但是BeanNameAutoProxyCreator的缺点很明显,它只能根据beanName来指定想要代理的Bean。
(2)简单使用
@Bean
public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
beanNameAutoProxyCreator.setBeanNames("userSe*");
beanNameAutoProxyCreator.setInterceptorNames("myAroundAdvise");
beanNameAutoProxyCreator.setProxyTargetClass(true);
return beanNameAutoProxyCreator;
}
4.DefaultAdvisorAutoProxyCreator
(1)介绍
根据继承关系可知DefaultAdvisorAutoProxyCreator类继承了AbstractAdvisorAutoProxyCreator类(AbstractAutoProxyCreator有个抽象方法getAdvicesAndAdvisorsForBean方法)
该类实现SmartInstantiationAwareBeanPostProcessor接口(该接口继承InstantiationAwareBeanPostProcessor接口【用于实例化的接口】)
(2)简单使用
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor() {
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.addMethodName("test");
DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
defaultPointcutAdvisor.setPointcut(pointcut);
defaultPointcutAdvisor.setAdvice(new MyAroundAdvice());
return defaultPointcutAdvisor;
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
(3)思想说明
1.通过DefaultAdvisorAutoProxyCreator会去找所有Advisor类型的Bean,根据Advisor中的PointCut和Advice信息,确定要代理的Bean以及代理逻辑。
2.但通过这种方式,我们得依靠某一个类来实现定义我们的Advisor,或者Advise,或者Pointcut。
3.要知道在bean的生命周期中存在BeanDefinition获取bean的元数据,为了更简化那就通过注解。
4.通过在类中的方法上通过某些注解,来定义PointCut以及Advice,如
@Pointcut("execution(public * com.xxx.test.service.*.*(..))")
public void pc1(){}
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("==============AspectAnnotation around前置通知=========");
Object result = joinPoint.proceed();
System.out.println("==============AspectAnnotation around后置通知=========");
return result;
@Around(""execution(public void com.xxx.test.service.UserService.test())"")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("==============AspectAnnotation around前置通知=========");
Object result = joinPoint.proceed();
System.out.println("==============AspectAnnotation around后置通知=========");
return result;
}
5.直接定义好了所要代理的方法(通过一个表达式),以及代理逻辑(被@Before修饰的方法),这样对于Spring来说,它要做的就是来解析这些注解了,解析之后得到对应的Pointcut对象、Advice对象,生成Advisor对象,扔进ProxyFactory中,进而产生对应的代理对象。
5.TargetSource
(1)介绍
AOP中,被代理对象就是Bean对象,是由BeanFactory给我们创建出来的,但Spring AOP中提供了TargetSource机制,可以让我们用来自定义逻辑来创建被代理对象。
(2)简单使用
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetSource(new TargetSource() {
@Override
public Class ? getTargetClass() {
return UserService.class;
@Override
public boolean isStatic() {
return true;
@Override
public Object getTarget() throws Exception {
return new UserService();
@Override
public void releaseTarget(Object target) throws Exception {
proxyFactory.addAdvice(new MyAroundAdvice());
proxyFactory.setProxyTargetClass(true);
proxyFactory.setFrozen(true); // frozen和static都为true,可以使得代理对象执行方法是保证被代理对象是同一个
UserService proxy = (UserService) proxyFactory.getProxy();
proxy.test();
(3)简单说明
1.首先proxyFactory要产生代理对象离不开被代理对象。那么我们要先知道setTarget与setTargetSource之间的关联:
public void setTarget(Object target) {
setTargetSource(new SingletonTargetSource(target));
@Override
public void setTargetSource(@Nullable TargetSource targetSource) {
this.targetSource = (targetSource != null ? targetSource : EMPTY_TARGET_SOURCE);
}
2.通过源码可以看到即使是设置Target,其实都会被包装成TargetSource,那么对应的要获取Target,也就只能调用TargetSource类#getTarget()方法。(说明proxy代理的不是target,而是TargetSource)
3.通常情况下,一个代理对象只能代理一个target,每次方法调用的目标也是唯一固定的target。但让proxy代理TargetSource,可以使得每次方法调用的target实例都不同(当然也可以相同,这取决于TargetSource实现)。这种机制使得方法调用变得灵活,可以扩展出很多高级功能,如:单利,原型,本地线程,目标对象池、运行时目标对象热替换目标源等等。(具体可查看 TargetSource目标源详解)
对AOP的理解
OOP表示面向对象编程,是一种编程思想,AOP表示面向切面编程,也是一种编程思想,而我们上面所描述的就是Spring为了让程序员更加方便的做到面向切面编程所提供的技术支持,也就说Spring提供了一套机制,可以让我们更加容易的来进行AOP,所以这套机制我们也可以称之为Spring AOP。
但提供的注解的方式来定义Pointcut和Advice,Spring并不是首创,首创是AspectJ,而且也不仅仅只有Spring提供了一套机制来支持AOP,还有比如 JBoss 4.0、aspectwerkz等技术都提供了对于AOP的支持。而且注解的方式,Spring是依赖了AspectJ的,Spring是直接把AspectJ中所定义的那些注解直接拿过来用,自己没有再重复定义了,也仅仅只是把注解的定义赋值过来了,每个注解具体底层是怎么解析的,还是Spring自己做的,所以在用Spring时,如果你想用@Before、@Around等注解,是需要单独引入aspecj相关jar包的。
注意:AspectJ是在编译时对字节码进行了修改,是直接在UserService类对应的字节码中进行增强的,也就是可以理解为是在编译时就会去解析@Before这些注解,然后得到代理逻辑,加入到被代理的类中的字节码中去的,所以如果想用AspectJ技术来生成代理对象 ,是需要用单独的AspectJ编译器的。我们在项目中很少这么用,仅仅只是用了@Before这些注解,而在启动Spring的过程中,Spring会去解析这些注解,然后利用动态代理机制生成代理对象的。
AOP中的核心概念
1. Aspect:表示切面,比如被@Aspect注解的类就是切面,可以在切面中去定义Pointcut、Advice等等
2. Join point:表示连接点,表示一个程序在执行过程中的一个点,比如一个方法的执行,比如一个异常的处理,在Spring AOP中,一个连接点通常表示一个方法的执行。
3. Advice:表示通知,表示在一个特定连接点上所采取的动作。Advice分为不同的类型,在Spring中是用Interceptor拦截器来实现Advice,并且在连接点周围维护一个Interceptor链。
4. Pointcut:表示切点,用来匹配一个或多个连接点,Advice与切点表达式是关联在一起的,Advice将会执行在和切点表达式所匹配的连接点上。
5. Introduction:可以使用@DeclareParents来给所匹配的类添加一个接口,并指定一个默认实现。(这种不怎么用)
示例
public interface CustomInterface {
public void custom();
public class DefaultCustomInterface implements CustomInterface{
@Override
public void custom() {
System.out.println("custom..");
@Aspect
@Component
public class MyAspect {
//这种方式需要引入AspectJ
@DeclareParents(value = "com.test.aop.introduction.CustomService", defaultImpl = DefaultCustomInterface.class)
private CustomInterface customInterface;
@ComponentScan
@Configuration
@EnableAspectJAutoProxy
public class IntroductionDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(IntroductionDemo.class);
CustomService customService = applicationContext.getBean(CustomService.class);
CustomInterface customInterface = (CustomInterface) customService;
customInterface.custom();
}
6. Target object:目标对象,被代理对象
7. AOP proxy:表示代理工厂,用来创建代理对象的,在Spring Framework中,要么是JDK动态代理,要么是CGLIB代理
8. Weaving:表示织入,表示创建代理对象的动作,这个动作可以发生在编译时期(比如Aspejctj),或者运行时【如Spring AOP】。
Advice在Spring AOP中对应API
(1)Aspject中的注解,其中有五个是用来定义Advice的,表示代理逻辑,以及执行时机:
1. @Before
2. @AfterReturning
3. @AfterThrowing
4. @After
5. @Around
(2)Spring自己也提供了类似的执行实际的实现类:
1. 接口MethodBeforeAdvice,继承了接口BeforeAdvice
2. 接口AfterReturningAdvice
3. 接口ThrowsAdvice
4. 接口AfterAdvice
5. 接口MethodInterceptor
(3)Spring会把五个注解解析为对应的Advice类:
1. @Before:AspectJMethodBeforeAdvice,实际上就是一个MethodBeforeAdvice
2. @AfterReturning:AspectJAfterReturningAdvice,实际上就是一个AfterReturningAdvice
3. @AfterThrowing:AspectJAfterThrowingAdvice,实际上就是一个MethodInterceptor
4. @After:AspectJAfterAdvice,实际上就是一个MethodInterceptor
5. @Around:AspectJAroundAdvice,实际上就是一个MethodInterceptor
ProxyFactory源码解析
1.怎么判断是使用哪种动态代理?
//ProxyFactory类#getProxy()方法
public Object getProxy() {
//createAopProxy()在底层筛选方式
//getProxy()方法返回代理对象
return createAopProxy().getProxy();
//ProxyCreatorSupport类#createAopProxy()方法
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
//调用DefaultAopProxyFactory类(实现类AopProxyFactory接口)#createAopProxy(AdvisedSupport config)方法
return getAopProxyFactory().createAopProxy(this);
//DefaultAopProxyFactory类#createAopProxy方法
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 是不是在GraalVM虚拟机上运行
if (!NativeDetector.inNativeImage()
// 如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk动态代理要快
// 或者isProxyTargetClass为true
// 或者ProxyFactory有没有添加接口[setInterfaces()方法]
(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.");
//被代理的类是接口【setTargetClass】
//判断是不是已经被代理的类
if (targetClass.isInterface() Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
return new ObjenesisCglibAopProxy(config);
else {
return new JdkDynamicAopProxy(config);
}
2.两种类型怎么产生动态代理的?
(1)CGLib动态代理
public Object getProxy() {
return getProxy(null);
//删减日志与抛出异常部分
//CglibAopProxy类#getProxy方法
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
// 被代理的类
Class ? rootClass = this.advised.getTargetClass();
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();
// 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) {..}
catch (Throwable ex) {..}
}
(2)JDK动态代理
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
//JdkDynamicAopProxy类#getProxy方法
public Object getProxy(@Nullable ClassLoader classLoader) {
// this实现了InvocationHandler
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
3.两种类型的执行逻辑是怎么样的?
(1)JDK动态代理
1.JdkDynamicAopProxy类#invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
// 拿到ProxyFactory的配置对象【属性值private final AdvisedSupport advised;(AdvisedSupport是实现ProxyConfig配置接口的)】
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
//判断如果被代理的目标对象要执行的方法是equal则执行JdkDynamicAopProxy(即代理对象的equal)方法,说明spring不对equal方法进行AOP拦截
if (!this.equalsDefined AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
//判断如果被代理的目标对象要执行的方法是hashcode则执行JdkDynamicAopProxy(即代理对象的hashcode)方法,同理spring也不对hashcode进行AOP拦截
else if (!this.hashCodeDefined AopUtils.isHashCodeMethod(method)) {
return hashCode();
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// 得到代理对象的类型,而不是所实现的接口
return AopProxyUtils.ultimateTargetClass(this.advised);
//判断如果被代理的对象本身就是实现了Advised接口,也不做处理,直接执行,说明spring不做切面的切面
else if (!this.advised.opaque method.getDeclaringClass().isInterface() method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
Object retVal;
// 如果ProxyFactory的exposeProxy为true(可以对外暴露),则将代理对象设置到currentProxy这个ThreadLocal中去
if (this.advised.exposeProxy) {
//将代理对象设置到currentProxy这个ThreadLocal中去,作用是能通过ThreadLocal获取当前的代理对象(能在自己写的方法里面拿到代理对象)
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
// 被代理对象和代理类
target = targetSource.getTarget();
Class ? targetClass = (target != null ? target.getClass() : null);
// 代理对象在执行某个方法时,根据方法筛选出匹配的Advisor,并适配成Interceptor
List Object chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
// 如果没有Advice,则直接调用对应方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
else {
//包装成方法对象反射调用句柄
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//传递句柄
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())) {
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()) {
targetSource.releaseTarget(target);
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
2.AdvisedSupport类#getInterceptorsAndDynamicInterceptionAdvice方法
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;
}
3.DefaultAdvisorChainFactory类#getInterceptorsAndDynamicInterceptionAdvice方法
//DefaultAdvisorChainFactory类#getInterceptorsAndDynamicInterceptionAdvice方法
public List Object getInterceptorsAndDynamicInterceptionAdvice( Advised config, Method method, @Nullable Class ? targetClass) {
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;
//遍历每个advisor
for (Advisor advisor : advisors) {
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封装成为Interceptor,当前Advisor中的Advice可能即是MethodBeforeAdvice,也是ThrowsAdvice
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
for (MethodInterceptor interceptor : interceptors) {
// 运行时,封装成对应的 InterceptorAndDynamicMethodMatcher 拦截器对象。
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
else {
interceptorList.addAll(Arrays.asList(interceptors));
// 最终,interceptorList中存储的是当前正在执行的Method所匹配的MethodInterceptor,可能动态的,也可能是非动态的,
// 找到Method所匹配的MethodInterceptor后,就会开始调用这些MethodInterceptor,如果是动态的,会额外进行方法参数的匹配
//下面便是采用了修饰器模式的思。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。