spring aop @aspectj的简单说明

1.AOP术语图片
这里写图片描述
2.spring切面应用的无五种通知
前置通知@Before :在目标方法调用之前执行。
后置通知@After:在目标方法调用之后调用,此时不会关系方法的返回是什么。
返回通知@AfterReturning:在被调用方法成功之后调用。
异常通知@AfterThrowing:在被调用方法异常之后调用。
环绕通知@Around:在包裹了被通知的方法,可以实现以上的所有通知。

3.其他注解介绍
@Aspect :注明这是一个切面
@Pointcut:声明一个切点
4.切点的限制符
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
5.在spring中使用还需要在配置xml中添加命名空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" **xmlns:aop="http://www.springframework.org/schema/aop"**
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
            http://www.springframework.org/schema/beans/spring-beans.xsd 
            http://www.springframework.org/schema/mvc  
            http://www.springframework.org/schema/mvc/spring-mvc.xsd  
            **http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd**
            http://www.springframework.org/schema/context  
            http://www.springframework.org/schema/context/spring-context-3.0.xsd"
    default-lazy-init="true">

**<aop:aspectj-autoproxy proxy-target-class="true" />**

6.使用代码

package com.xyy.aspect;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AopLog extends LogAspect {
    private Logger logger = LogManager.getLogger(AopLog.class.getName());

    @Pointcut("execution(public * com.xyy.controller.*.*(..))")
    public void recordControllerLog() {
    }

    @Pointcut("execution(public * com.xyy.serviceImpl.*.*(..))")
    public void recordServiceImplLog() {
    }
    @Before("recordControllerLog()")
    public void beforeController() throws Throwable {
    logger.info("-----Controller---begin-----");
    }
    @Around("recordControllerLog()")
    // @Around("execution(* com.xyy.controller.*.*(..))") //execution(* com.xyy.controller.**.*.*(..))<.** 表示controller下面还有包>
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    logger.info("-----打印请求日志-----");
    return super.logInController(joinPoint);
    }
    @After("recordControllerLog()")
    public void afterController() throws Throwable {
    logger.info("-----Controller---end-----");
    }
    @Before("recordServiceImplLog()")
    public void beforeServiceImpl() throws Throwable {
    logger.info("-----ServiceImpl---begin-----");
    }
    @After("recordServiceImplLog()")
    public void afterServiceImpl() throws Throwable {
    logger.info("-----ServiceImpl---end-----");
    }
}

2.0版本

package com.xyy.springboot.configuration;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * springboot自动开启aop
 */
@Aspect
@Component
public class BaseLogAspect {
    private static final Logger log = LoggerFactory.getLogger(BaseLogAspect.class);

    /**
     *  execution:用于匹配方法执行的连接点;
     *      *:匹配任何数量字符;
            ..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
            +:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。
                 java.lang.String    匹配String类型;
                 java.*.String       匹配java包下的任何“一级子包”下的String类型;
                 如匹配java.lang.String,但不匹配java.lang.ss.String
                 java..*            匹配java包及任何子包下的任何类型;
                 如匹配java.lang.String、java.lang.annotation.Annotation
                 java.lang.*ing      匹配任何java.lang包下的以ing结尾的类型;
                 java.lang.Number+  匹配java.lang包下的任何Number的自类型;
                 如匹配java.lang.Integer,也匹配java.math.BigInteger
        within:用于匹配指定类型内的方法执行;
        this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
        target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
        args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
        @within:用于匹配所有持有指定注解类型内的方法;
        @target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;
        @args:用于匹配当前执行的方法传入的参数持有指定注解的执行;
        @annotation:用于匹配当前执行方法持有指定注解的方法;
        bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;
        reference pointcut:表示引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持。
     */
//    只能注释在方法上
    @Pointcut("@annotation(com.xyy.springboot.configuration.BaseMethodLog)")
//    注释在类上,使方法都应用
//    @Pointcut("@within(com.xyy.springboot.configuration.BaseTypeLog)")
    public void pointcut(){}

    @Before("pointcut()")
    public void logStart(JoinPoint joinPoint){
        // 方法名称
        String methodName = joinPoint.getSignature().getName();
        // 方法参数
        Object[] args = joinPoint.getArgs();
        List<Object> list = Arrays.asList(args);
        log.debug(methodName + "方法运行前,参数" + list.toString());
    }

    //如果是别的类调用这个切点,需要写全类名
    //无论目标方法是否出现异常都会执行
    @After("com.xyy.springboot.configuration.BaseLogAspect.pointcut()")
    public void logEnd(JoinPoint joinPoint){
        // 方法名称
        String methodName = joinPoint.getSignature().getName();
        log.debug(methodName + "方法运行后");
    }

    @AfterReturning(value = "pointcut()", returning = "result")
    public void logReturn(JoinPoint joinPoint, Object result){
        // 方法名称
        String methodName = joinPoint.getSignature().getName();
        if (null != result)
            log.debug(methodName + "方法运行结束,结果" + result.toString());
        else
            log.debug(methodName + "方法运行结束");
    }

    @AfterThrowing(value = "pointcut()", throwing = "exception")
    public void logReturn(JoinPoint joinPoint, Exception exception){
        // 方法名称
        String methodName = joinPoint.getSignature().getName();
        log.debug(methodName + "方法运行异常", exception);
    }

}

猜你喜欢

转载自blog.csdn.net/u012562117/article/details/52851293