26.spring系列- @EnableAspectJAutoProxy、@Aspect中通知顺序详解

@EnableAspectJAutoProxy自动为bean创建代理对象

@EnableAspectJAutoProxy可以自动为spring容器中符合条件的bean创建代理对象,@EnableAspectJAutoProxy需要结合@Aspect注解一起使用。

案例

来一个配置

@ComponentScan
@Configuration
//开启AspectJ注解
@EnableAspectJAutoProxy
public class MainConfig {
}

来两个方法:

@Component
public class CarService {

    public void sayCar(){
        System.out.println("carService");
    }
}

@Component
public class UserService {

    public void sayUser(){
        System.out.println("userService");
    }
}

来个切面:

@Aspect
@Component
public class MyAspect {

    @Pointcut("execution(* com.spring.beanAOP6..*(..))")
    public void pointCut() {

    }

    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String name = signature.getMethod().getName();
        System.out.println(String.format("进入%s方法", name));
    }
}

测试:

@Test
    public void testAop11(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
        CarService carService = context.getBean("carService", CarService.class);
        carService.say();
        com.spring.beanAOP6.UserService userService = context.getBean("userService", com.spring.beanAOP6.UserService.class);
        userService.say();
    }

运行结果:

进入sayCar方法
carService
进入sayUser方法
userService

AspectJ中有几个关键信息

  • 使用@Component将这个类注册到spring容器中
  • 使用@Aspect标注这是一个AsectJ来定义通知的配置类
  • 定义切点,目前的配置。会拦截beanAOP6包中以及其子包中所有类的所有方法。
  • 定义一个前置通知,这个通知会对@Pointcut定义的切入点起效

通知执行顺序

@EnaleAspectJAutoProxy允许spring容器中通过Advisor 、@Aspect 来定义通知,当spring容器中存在多个Advisor、@Aspect时,组成的拦截器调用链顺序是什么样的呢?在介绍这个之前,我们需要先回顾一下aop中4种通知相关知识。

spring aop中4种通知(Advice)

  1. MethodInterceptor
  2. MethodBeforeAdvice
  3. AfterReturningAdvice
  4. ThrowsAdvice

所有的通知最终都需要转换成MethodInterceptor类型的通知,然后组成一个MethodInterceptor列表,我们称之为方法调用链或者拦截器链,上面列表中后面3个通过下面的转换器将其包装为MethodInterceptor类型的通知

  1. MethodBeforeAdvice -> MethodBeforeAdviceInterceptor
  2. AfterReturningAdvice -> AfterReturningAdviceInterceptor
  3. ThrowsAdvice -> ThrowsAdviceInterceptor

org.aopalliance.intercept.MethodInterceptor:方法拦截器

方法拦截器,这个比较强大,可以在方法执行前后执行一些增强操作,其他类型的通知最终都会被包装为 MethodInterceptor 来执行。

下面我们自定义一个MethodInterceptor

class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("我是MethodInterceptor start");
        //调用invocation.proceed()执行下一个拦截器
        Object result = invocation.proceed();
        System.out.println("我是MethodInterceptor end");
        //返回结果
        return result;
    }
}

org.springframework.aop.MethodBeforeAdvice:方法前置通知

方法前置通知,可以在方法之前定义增强操作。

下面我们自定义一个MethodBeforeAdvice

class MyMethodBeforeAdvice implements MethodBeforeAdvice {

    @Override
    public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
        System.out.println("我是MethodBeforeAdvice");
    }
}

MethodBeforeAdvice最终会被包装为MethodBeforeAdviceInterceptor类型,然后放到拦截器链中去执行,通过MethodBeforeAdviceInterceptor代码可以理解MethodBeforeAdvice的执行过程

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

	private final MethodBeforeAdvice advice;


	/**
	 * Create a new MethodBeforeAdviceInterceptor for the given advice.
	 * @param advice the MethodBeforeAdvice to wrap
	 */
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}


	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
	 	//调用MethodBeforeAdvice的before方法,执行前置通知
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		//执行下一个拦截器
		return mi.proceed();
	}

}

org.springframework.aop.AfterReturningAdvice:方法返回通知

方法返回通知,用来在方法执行完毕之后执行一些增强操作。

下面我们自定义一个AfterReturningAdvice

class MyAfterReturningAdvice implements AfterReturningAdvice {

    @Override
    public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
        System.out.println("我是AfterReturningAdvice");
    }
}

AfterReturningAdvice最终会被包装为AfterReturningAdviceInterceptor类型,然后放到拦截器链中去执行,通过AfterReturningAdviceInterceptor代码可以理解AfterReturningAdvice的执行过程

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

    private final AfterReturningAdvice advice;

    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
        this.advice = advice;
    }


    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        //执行下一个拦截器,可以获取目标方法的返回结果
        Object retVal = mi.proceed();
        //调用方法返回通知的afterReturning方法,会传入目标方法的返回值等信息
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }

}

org.springframework.aop.ThrowsAdvice:异常通知

当目标方法发生异常时,可以通过 ThrowsAdvice 来指定需要回调的方法,我们在此可以记录一些异常信息,或者将异常信息发送到监控系统等。

下面我们自定义一个ThrowsAdvice

/**
 * 用来定义异常通知
 * 方法名必须是afterThrowing,格式参考下面2种定义
 * 1. public void afterThrowing(Exception ex)
 * 2. public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
 */
class MyThrowsAdvice implements ThrowsAdvice {
    public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
        System.out.println("我是ThrowsAdvice");
    }
}

ThrowsAdvice最终会被包装为ThrowsAdviceInterceptor类型,然后放到拦截器链中去执行,通过ThrowsAdviceInterceptor代码可以理解ThrowsAdvice的执行过程,ThrowsAdviceInterceptor 构造参数传入一个自定义的 ThrowsAdvice 对象

public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {

    private final Object throwsAdvice;

    public ThrowsAdviceInterceptor(Object throwsAdvice) {
        this.throwsAdvice = throwsAdvice;
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        } catch (Throwable ex) {
            //调用 ThrowsAdvice 中的 afterThrowing 方法来处理异常
            this.throwsAdvice.afterThrowing(。。。。);
            //将异常继续往外抛
            throw ex;
        }
    }
}

拦截器链执行过程

假如目标方法上面有好几个通知,调用目标方法执行,spring会将所有的通知转换得到一个MethodInterceptor列表,然后依次按照下面的方式执行,会先调用第一个拦截器的MethodInterceptor#invoke(MethodInvocation invocation)方法,会传递一个MethodInvocation类型的参数,在此方法中,我们可以调用MethodInvocation#processd方法去执行第二个拦截器,然后依次按照这样的过程执行,到了最后一个MethodInterceptor中,再次调用MethodInvocation#processd时,会调用目标方法。
在这里插入图片描述4种通知的执行顺序

结合上面的过程,假如目标方法上面依次添加了下面4中通知,我们来分析一下他们的执行过程

class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("我是MethodInterceptor start");
        //调用invocation.proceed()执行下一个拦截器
        Object result = invocation.proceed();
        System.out.println("我是MethodInterceptor end");
        //返回结果
        return result;
    }
}

class MyMethodBeforeAdvice implements MethodBeforeAdvice {

    @Override
    public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
        System.out.println("我是MethodBeforeAdvice");
    }
}

class MyAfterReturningAdvice implements AfterReturningAdvice {

    @Override
    public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
        System.out.println("我是AfterReturningAdvice");
    }
}

class MyThrowsAdvice implements ThrowsAdvice {
    public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
        System.out.println("我是ThrowsAdvice");
    }
}

根据通知的规定,非MethodInterceptor类型的通知,都会被包装为MethodInterceptor类型的,上面除了第一个之外,其他3个都会被转换为MethodInterceptor,转换之后变成了下面这样:

class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        System.out.println("我是MethodInterceptor start");
        //调用mi.proceed()执行下一个拦截器
        Object retVal = mi.proceed();
        System.out.println("我是MethodInterceptor end");
        //返回结果
        return retVal;
    }
}

class MyMethodBeforeAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        System.out.println("我是MethodBeforeAdvice");
        //调用mi.proceed()执行下一个拦截器
        Object retVal = mi.proceed();
        return retVal;
    }
}

class MyAfterReturningAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        //调用mi.proceed()执行下一个拦截器
        Object retVal = mi.proceed();
        System.out.println("我是AfterReturningAdvice");
        return retVal;
    }
}

class MyThrowsAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            //调用mi.proceed()执行下一个拦截器
            return mi.proceed();
        } catch (Throwable ex) {
            System.out.println("我是ThrowsAdvice");
            throw ex;
        }
    }
}

根据通知链的执行过程,最终变成了下面这样:

System.out.println("我是MethodInterceptor start");
System.out.println("我是MethodBeforeAdvice");
Object retVal = null;
try {
    retVal = 通过反射调用目标方法获取返回值;
} catch (Throwable ex) {
    System.out.println("我是ThrowsAdvice");
    throw ex;
}
System.out.println("我是AfterReturningAdvice");
System.out.println("我是MethodInterceptor end");
return retVal;

我们来个案例验证一下:

public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("MyMethodInterceptor start");
        Object proceed = invocation.proceed();
        System.out.println("MyMethodInterceptor end");
        return proceed;
    }
}

public class MyMethodBeforeInterceptor implements MethodBeforeAdvice {

    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("MyMethodBeforeInterceptor before");
    }
}

public class MyMethodAfterInterceptor implements AfterReturningAdvice {

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("MyMethodAfterInterceptor after");
    }
}

public class MyMethodThrowInterceptor implements ThrowsAdvice {

    public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
        System.out.println("MyMethodThrowInterceptor");
    }
}
public class UserService {

    public void say(){
        System.out.println("userService --> say方法");
    }
}

测试:

@Test
    public void testAop12(){
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvice(new MyMethodInterceptor());
        proxyFactory.addAdvice(new MyMethodAfterInterceptor());
        proxyFactory.addAdvice(new MyMethodThrowInterceptor());
        proxyFactory.addAdvice(new MyMethodBeforeInterceptor());
        proxyFactory.setTarget(new com.spring.beanAOP7.UserService());
        com.spring.beanAOP7.UserService proxy = (com.spring.beanAOP7.UserService) proxyFactory.getProxy();
        proxy.say();

    }

运行结果:

MyMethodInterceptor start
MyMethodBeforeInterceptor before
userService --> say方法
MyMethodAfterInterceptor after
MyMethodInterceptor end

单个@Aspect中多个通知的执行顺序

@Aspect标注的类中可以使用下面5中注解来定义通知

@Before
@Around
@After
@AfterReturning
@AfterThrowing

当单个@Aspect中定义了多种类型的通知时,@EnableAspectJAutoProxy内部会对其进行排序,排序顺序如下

@AfterThrowing
@AfterReturning
@After
@Around
@Before

下面我们来个@Aspect类,同时定义5种通知,然后来一步步分析一下其执行的属性。

@Component
public class ColorService {

    public String color(){
        System.out.println("color");
        return "color";
    }
}

@ComponentScan
@Configuration
@EnableAspectJAutoProxy
public class MainConfig {

}
@Aspect
@Component
public class MyAspect {

    @Pointcut("execution(* com.spring.beanAOP8.ColorService.*(..))")
    public void pc() {
    }

    @Before("pc()")
    public void before() {
        System.out.println("@Before通知!");
    }

    @Around("pc()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("@Around通知start");
        Object result = joinPoint.proceed();
        System.out.println("@Around绕通知end");
        return result;
    }

    @After("pc()")
    public void after() throws Throwable {
        System.out.println("@After通知!");
    }

    @AfterReturning("pc()")
    public void afterReturning() throws Throwable {
        System.out.println("@AfterReturning通知!");
    }

    @AfterThrowing("pc()")
    public void afterThrowing() {
        System.out.println("@AfterThrowing通知!");
    }
}
 @Test
    public void testAop13(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(com.spring.beanAOP8.MainConfig.class);
        ColorService colorService = context.getBean("colorService", ColorService.class);
        colorService.color();
    }
@Around通知start
@Before通知!
color
@AfterReturning通知!
@After通知!
@Around绕通知end

这输出好像和我们上面说的不一样的???

排序规则和输出结果都没有问题,我们分析分析

@Aspect中5种通知回顾

5种通知对应的Advice类

  • @AfterThrowing --> AspectJAfterThrowingAdvice
  • @AfterReturning --> AspectJAfterReturningAdvice
  • @After --> AspectJAfterAdvice
  • @Around --> AspectJAroundAdvice
  • @Before --> AspectJMethodBeforeAdvice

@AfterThrowing:AspectJAfterThrowingAdvice

public class AspectJAfterThrowingAdvice implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            //执行下一个拦截器
            return mi.proceed();
        } catch (Throwable ex) {
            //通过反射调用@AfterThrowing标注的方法
            //继续抛出异常
            throw ex;
        }
    }
}

AspectJAfterThrowingAdvice 实现了 MethodInterceptor 接口,不需要进行包装。

@AfterReturning:AspectJAfterReturningAdvice

public class AspectJAfterReturningAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
        // 调用@AfterReturning标注的方法
    }
}

AspectJAfterReturningAdvice 实现了 AfterReturningAdvice 接口,是一个方法返回通知,不是MethodInterceptor类型的,所以最终需包装为MethodInterceptor类型,变成下面这样

public class AspectJAfterReturningAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        //执行下一个拦截器
        Object retVal = mi.proceed();
        //调用@AfterReturning标注的方法
        return retVal;
    }
}

@After:AspectJAfterAdvice

public class AspectJAfterAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            //执行下一个拦截器
            return mi.proceed();
        } finally {
            //调用@After标注的方法
        }
    }
}

AspectJAfterAdvice 实现了 MethodInterceptor接口,所以最终执行的时候不需要进行包装。

注意 invoke 方法内部使用了 try…finally 的方式,@After方法的调用放在了finally中,所以不管是否有异常,@After类型的通知都会被执行。

@Around:AspectJAroundAdvice

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        return 调用 @Around标注的方法 ;
    }
}

AspectJAroundAdvice 实现了 MethodInterceptor接口,最终执行的时候也不需要进行包装。

@Before:AspectJMethodBeforeAdvice

public class AspectJMethodBeforeAdvice implements MethodBeforeAdvice, Serializable {
    @Override
    public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
        invokeAdviceMethod(getJoinPointMatch(), null, null);
    }
}

AspectJMethodBeforeAdvice 实现了 MethodBeforeAdvice接口,是一个前置通知,不是MethodInterceptor类型的,所以最终需包装为MethodInterceptor类型,变成下面这样

public class AspectJMethodBeforeAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        //调用@Before标注的方法
        //执行下一个拦截器
        return mi.proceed();
    }
}

我们在来看下定义的通知

@Aspect
@Component
public class MyAspect {

    @Pointcut("execution(* com.spring.beanAOP8.ColorService.*(..))")
    public void pc() {
    }

    @Before("pc()")
    public void before() {
        System.out.println("@Before通知!");
    }

    @Around("pc()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("@Around通知start");
        Object result = joinPoint.proceed();
        System.out.println("@Around绕通知end");
        return result;
    }

    @After("pc()")
    public void after() throws Throwable {
        System.out.println("@After通知!");
    }

    @AfterReturning("pc()")
    public void afterReturning() throws Throwable {
        System.out.println("@AfterReturning通知!");
    }

    @AfterThrowing("pc()")
    public void afterThrowing() {
        System.out.println("@AfterThrowing通知!");
    }
}

我们给出的结论是,会按照下面的顺序执行

@AfterThrowing -> @AfterReturning -> @After -> @Around -> @Before

按照上面的顺序,一步步来分析。

先执行第1个通知@AfterThrowing,变成下面这样

try {
    //执行下一个拦截器
    return mi.proceed();
} catch (Throwable ex) {
    System.out.println("@AfterThrowing通知!");
    //继续抛出异常
    throw ex;
}

mi.processed()会执行第2个通知@AfterReturning,变成了下面这样

try {
    //执行下一个拦截器
    Object retVal = mi.proceed();
    System.out.println("@AfterReturning通知!");
    return retVal;
} catch (Throwable ex) {
    System.out.println("@AfterThrowing通知!");
    //继续抛出异常
    throw ex;
}

继续mi.proceed()执行第3个通知@After,变成了下面这样

try {
    Object result = null;
    try {
        //执行下一个拦截器
        result = mi.proceed();
    } finally {
        System.out.println("@After通知!");
    }
    System.out.println("@AfterReturning通知!");
    return retVal;
} catch (Throwable ex) {
    System.out.println("@AfterThrowing通知!");
    //继续抛出异常
    throw ex;
}

继续mi.proceed()执行第4个通知@Around,变成了下面这样

try {
    Object result = null;
    try {
        System.out.println("@Around通知start");
        result = joinPoint.proceed();
        System.out.println("@Around绕通知end");
        return result;
    } finally {
        System.out.println("@After通知!");
    }
    System.out.println("@AfterReturning通知!");
    return retVal;
} catch (Throwable ex) {
    System.out.println("@AfterThrowing通知!");
    //继续抛出异常
    throw ex;
}

继续joinPoint.proceed()执行第5个通知@Before,变成了下面这样

try {
    Object result = null;
    try {
        System.out.println("@Around通知start");
        System.out.println("@Before通知!");
        result = mi.proceed();
        System.out.println("@Around绕通知end");
        return result;
    } finally {
        System.out.println("@After通知!");
    }
    System.out.println("@AfterReturning通知!");
    return retVal;
} catch (Throwable ex) {
    System.out.println("@AfterThrowing通知!");
    //继续抛出异常
    throw ex;
}

继续joinPoint.proceed()会调用目标方法,变成了下面这样

try {
    Object result = null;
    try {
        System.out.println("@Around通知start");
        System.out.println("@Before通知!");
        result = // 通过反射调用目标方法;
        System.out.println("@Around绕通知end");
        return result;
    } finally {
        System.out.println("@After通知!");
    }
    System.out.println("@AfterReturning通知!");
    return retVal;
} catch (Throwable ex) {
    System.out.println("@AfterThrowing通知!");
    //继续抛出异常
    throw ex;
}

所以最终输出

@Around通知start
@Before通知!
@Around绕通知end
@After通知!
@AfterReturning通知!

@EnableAspectJAutoProxy中为通知指定顺序

@EnableAspectJAutoProxy用在spring环境中,可以通过@Aspect以及Advisor来定义多个通知,当spring容器中有多个@Aspect、Advisor时,他们的顺序是什么样的呢?

我们先看一下如何为@Aspect、自定义Advisor指定顺序。

为@Aspect指定顺序:用@Order注解

需要在@Aspect标注的类上使用@org.springframework.core.annotation.Order注解,值越小,通知的优先级越高。

为Advisor指定顺序:实现Ordered接口

自定义的Advisor通过org.springframework.core.Ordered接口来指定顺序,这个接口有个public int getOrder()方法,用来返回通知的顺序。

spring为我们提供了一个Advisor类型的抽象类org.springframework.aop.support.AbstractPointcutAdvisor,这个类实现了Ordered接口,spring中大部分Advisor会是继承AbstractPointcutAdvisor,若需要自定义Advisor,也可以继承这个类,这个类的getOrder方法比较关键,来看一下

public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable {

    @Nullable
    private Integer order;

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        //若当前Advisor指定了order,则直接返回
        if (this.order != null) {
            return this.order;
        }
        //获取当前类中配置的通知对象Advice
        Advice advice = getAdvice();
        //若advice实现了Ordered接口,这从advice中获取通知的顺序
        if (advice instanceof Ordered) {
            return ((Ordered) advice).getOrder();
        }
        //否则通知的优先级最低,Integer.MAX_VALUE
        return Ordered.LOWEST_PRECEDENCE;
    }
}

Spring为我们提供了一个默认的Advisor类:DefaultPointcutAdvisor,这个类就继承了AbstractPointcutAdvisor,通常我们可以直接使用DefaultPointcutAdvisor来自定义通知。

多个@Aspect、Advisor排序规则

排序规则

1、在spring容器中获取@Aspect、Advisor类型的所有bean,得到一个列表 list1

2、对list1按照order的值升序排序,得到结果list2

3、然后再对list2中@Aspect类型的bean内部的通知进行排序,规则
@AfterThrowing -> @AfterReturning -> @After -> @Around -> @Before

4、最后运行的时候会得到上面排序产生的方法调用链列表去执行。

案例不写了,大家下去可以自己尝试一下

@EnableAspectJAutoProxy另外2个功能

这个注解还有2个参数,大家看一下下面的注释,比较简单,就不用案例演示了。

public @interface EnableAspectJAutoProxy {

 /**
  * 是否基于类来创建代理,而不是基于接口来创建代理
  * 当为true的时候会使用cglib来直接对目标类创建代理对象
  * 默认为 false:即目标bean如果有接口的会采用jdk动态代理来创建代理对象,没有接口的目标bean,会采用cglib来创建代理对象
  */
 boolean proxyTargetClass() default false;

 /**
  * 是否需要将代理对象暴露在ThreadLocal中,当为true的时候
  * 可以通过org.springframework.aop.framework.AopContext#currentProxy获取当前代理对象
  */
 boolean exposeProxy() default false;

}

@EnableAspectJAutoProxy原理

@EnableAspectJAutoProxy会在spring容器中注册一个bean:AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator是BeanPostProcessor类型的,BeanPostProcessor大家应该比较熟悉了,bean后置处理器,可以在bean声明周期中对bean进行操作,比如对bean生成代理等;而AnnotationAwareAspectJAutoProxyCreator就是对符合条件的bean,自动生成代理对象,源码就这里就不细说了,有兴趣的可以从postProcessAfterInitialization方法看,比较简单。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值