Spring注解开发8 --- AOP注解

AOP方法上的注解有:

@Before():这个是前置调用,在方法之前掉调用

@After() 这个称为后置调用,不管方法执行是正常还是异常都会调用

@Around() 这个表示的是环绕 在调用方法之前和之后调用 一般用来记录日志,需要joinPoint.proceed()推动目标进行

@AfterReturning()这个表示的是正常运行后,返回数据的时候调用

@AfterThrowing()这个表示的是抛出异常的时候调用

@Aspect:告诉容器这是一个切面类

@Pointcut() :切入点表达式的位置

@EableAspectjAutoProxy:开启基于注解的aop模式,原来是在xml中配置

例子:

1.需要导入包

 <dependency>
      <groupId>org.springframework</groupId>
       <artifactId>spring-aspects</artifactId>
      <version>5.0.8.RELEASE</version>
</dependency>

2.业务类

public class Caculator {

    public Integer cal(int a,int b) {
        System.out.println("Caculator ..cal");
        return  a/b;
    }
}

3.切面类

@Aspect
public class LogsAspects {

    @Pointcut("execution( * com.wusu.aop.Caculator.*(..))")
    public void pointcut(){};

    @Before("pointcut()")
    public void logStart(JoinPoint joinPoint){
        System.out.println("开始计算"+joinPoint.getSignature().getName()+": 参数是:"+ Arrays.asList(joinPoint.getArgs()).toString());
    }
    @After("pointcut()")
    public void logEnd(JoinPoint joinPoint){
        System.out.println("结束计算"+joinPoint.getSignature().getName());
    }
    //这个JoinPoint必须放在第一个才能使用
    @AfterReturning(value = "pointcut()",returning = "result")
    public void logReturn(JoinPoint joinPoint,Object result){
        System.out.println("开始返回"+joinPoint.getSignature().getName()+",return :"+ result);
    }
    @Around("pointcut()")  //这个必须要有返回值值,否则正常的有返回值的没有结果
    public Object logRound(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕执行前。。。参数是:"+joinPoint.getArgs());
        Object object = joinPoint.proceed(joinPoint.getArgs());
        System.out.println("环绕执行后。。。参数是:"+joinPoint.getArgs());
        return object;
    }
    @AfterThrowing(value = "pointcut()",throwing = "exception")
    public void logThrowing(Exception exception){
        System.out.println("抛出异常"+exception);
    }
}

对于@PointCut里面的表达式解释:

定义切入点表达式

 1>:定义一个没有实现的方法

2>:在这个方法上 使用切入点表达式的注解Pointcut

execution ()你记成语法规则

 第一个 * 代表的是返回注入方法的返回数据的类型

第二个 * 代表的是UserDAO这个类里面的所有方法

“..” 代表的是注入方法里面的参数类型 这里因为可以是任意类型 所以使用 “..” ,这里是两个点

4. 配置类,业务类和切面类都需要放入IOC容器中

         需要使用@EnableAspectJAutoProxy开启自动代理

@EnableAspectJAutoProxy
@Configuration
public class MainConfig {
    @Bean
    public Caculator caculator(){
        return  new Caculator();
    }
    @Bean
    public LogsAspects logsAspects(){
        return new LogsAspects();
    }
}

5.测试类,需要从IOC容器中获取这个业务类才是被代理后的类

public class TestAop {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        Caculator caculator = applicationContext.getBean(Caculator.class);
        int cal = caculator.cal(16, 0);

    }
}

结果显示:

开始计算cal: 参数是:[16, 0]
Caculator ..cal
结束计算cal
抛出异常java.lang.ArithmeticException: / by zero

猜你喜欢

转载自blog.csdn.net/weixin_40792878/article/details/82823885