likes
comments
collection
share

sonic-agent是如何开启目标类切面的

作者站长头像
站长
· 阅读数 20

先从sonic-agent的启动类一个注解说起,虽然这个注解貌似没有在全局代码中发挥作用,应该是可以拿掉的。但是作为学习探究,那还是可以看看这个注解到底是干啥,慢慢的积累。

开启目标类切面注解

先看下面的启动类代码。

@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@EnableAspectJAutoProxy

来一点专业的解释

@EnableAspectJAutoProxy注解是用于启用AspectJ自动代理功能的注解。它告诉Spring容器在扫描到带有@Aspect注解的切面类时,自动创建对应的代理对象,并将其纳入Spring的AOP(面向切面编程)框架中。

具体含义如下:

1.@EnableAspectJAutoProxy注解告诉Spring容器启用AspectJ自动代理功能。AspectJ是一个强大的AOP框架,它提供了一种在运行时通过动态代理实现横切关注点的能力。 2.proxyTargetClass = true参数指示Spring使用CGLIB库来生成代理对象。默认情况下,如果目标类实现了至少一个接口,则使用JDK动态代理。如果目标类没有实现任何接口,或者proxyTargetClass设置为true,则使用CGLIB库生成代理对象。CGLIB是一个基于字节码的代码生成库,它可以在运行时动态地生成被代理类的子类。

通过@EnableAspectJAutoProxy注解,你可以方便地使用Spring的AOP功能,并将自定义的切面逻辑应用于目标类的方法调用。使用该注解后,Spring将自动创建代理对象,并在目标方法执行前、执行后或抛出异常时,调用切面中定义的增强逻辑。

总之,@EnableAspectJAutoProxy注解的作用是启用AspectJ自动代理功能,并配置代理对象的生成方式(使用CGLIB还是JDK动态代理)。这样,你就可以使用AOP编程范式来实现横切关注点的功能。 就是说这个注解可以对目标类进行切面,proxyTargetClass = true的含义是可以直接对没有实现接口的目标类采用cglib库生成代理对象。可以完成对目标类中的方法进行切面处理。

上手实践

还是通过demo的方式来说明吧,看下面的demo示例

@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

定义一个类,并在类中定义几个方法,注意,这个类没有实现接口,如果实现了接口,会默认使用jdk的动态代理,没有实现的话,就会走cglib代理

@Service
public class UserService {
    public void showName(){
        System.out.println("showName method called!");
    }
    public void showAge(){
        System.out.println("showAge method called!");
    }
}

最后定义一个切面类,对UserService这个类进行切面操作,这里只是简单的对方法执行前后打印一个日志

@Aspect
@Component
public class UserAspect {

    @Before("execution(* com.example.demo.service.UserService.*(..))")
    public void beforeAdvice(JoinPoint joinPoint){
        System.out.println("Before execute method: " + joinPoint.getSignature().getName());
    }

    @After("execution(* com.example.demo.service.UserService.*(..))")
    public void afterAdvice(JoinPoint joinPoint){
        System.out.println("After execute method: " + joinPoint.getSignature().getName());
    }
}

输出结果:

Before execute method: showAge
showAge method called!
After execute method: showAge
Before execute method: showName
showName method called!
After execute method: showName

这个主要是对目标类切面调用,对于注解annotation而言,注解显然可以达到更细的粒度。EnableAspectAutoProxy只是启用了Spring的AOP功能,并根据切面类的注解创建代理对象,并将其应用在方法上,但是如果需要具体指定哪些方法的话,还得需要自定义注解来定义切点

@EnableAspectJAutoProxy注解和自定义的注解(annotation)是互相配合使用的。前者用于启用AOP功能并创建代理对象,后者用于指定切点和增强逻辑。

结论

实际上,@EnableAspectJAutoProxy注解是为某些业务类提供了一个便捷的切面处理方法,与annotation相比,粒度更粗,一般应用中粒度更细的话会直接选annotation注解的方式。