springboot AOP 实现日志管理

本文使用注解进行spring AOP的实现。

1.AOP的基本概念

(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知

(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用

(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around

(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式

2.用到的注解

1.@Aspect 注解位置为类,声明切面。

2.@PointCut 声明切点,支持俩种类型,一种是execution表达式,一种是注解形式的。

execution表达式:
execution(* com.test.aspect.service.*.*(..))  第一个* 代表的是所有返回值类型,第二个*代表的是包下所有的类,第三个*代表的是类下所有的方法,()里的..代表的是所有参数类型

注解:
@annotation(com.test.aspect.LogOperate)

3.@Around 环绕增强

4.@Before 前置增强

5.@After 后置增强

6.@AfterThrowing 异常增强

3.具体实现

1.日志一般使用的是注解类型的切点表达式,我们先创建一个日志注解,当spring容器扫描到有此注解的方法就会进行增强。

@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogOperate {

}

2.切点声明:

@Component  //声明为组件,可有容器管理
@Aspect      
public class LogAdvice {

    @Pointcut("@annotation(com.test.aspect.LogOperate)")   //切点
    public void log(){

    }

    @Around(value = "log()")       //环绕增强,切点为log这个切点
    public void around(ProceedingJoinPoint point) throws Throwable {     //这里使用参数为ProceedingJoinPoint 类型,只有环绕增强可以使用,并且在方法中必须执行proceed方法,否则被增强的方法不会执行
        System.out.println("around exec");
        point.proceed();
    }

    @Before(value = "log()")            //除了环绕增强,其他使用的是joinPoint 类型
    public void before(JoinPoint point) throws Throwable {
        System.out.println("before exec");
    }

    @After(value = "log()")
    public void after(JoinPoint point) throws Throwable {
        System.out.println("after exec");
    }

    @AfterThrowing("log()")
    public void afterThrowing(JoinPoint point){
        System.out.println("after throw");
    }

3.声明一个使用注解的类

public class Service {

    @LogOperate
    public void operate(){
            System.out.println("operate exec");
    }
}

4.Java配置类

@Configuration
@ComponentScan(basePackages = "com.test.aspect")
@EnableAspectJAutoProxy   //开启对AOP的支持,在springboot里无需此注解
public class Config {

    @Bean
    public Service service(){
        return new Service();
    }
}

5.Java测试类:

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        Service bean = context.getBean(Service.class);
        bean.operate();
    }
}

/*结果:
around exec
before exec
operate exec
after exec  */

6.出现的问题:

通过反射获取方法参数名会出现错误,不是原来的参数名,而是arg1,arg2....,解决方法是在  pom的编译插件中添加一个参数:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.3</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <compilerArgs>
            <arg>-parameters</arg>
        </compilerArgs>
    </configuration>
</plugin>

这样就可以获取到正常对的参数名了

猜你喜欢

转载自blog.csdn.net/qq_39158142/article/details/82872205