转载

AOP系列(二) Spring AOP

Spring AOP 提供全面的 AOP 解决方案。Spring 将 Spring AOP 和 IOC 与 AspectJ 无缝集成,以便在一致的 Spring-based application architecture 中满足 AOP 的所有使用需求。

二、SpringBoot集成Spring-Aop

添加依赖

maven依赖添加如下
<!--引入SpringBoot的Web模块-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
<!--引入AOP依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
复制代码

注意:在完成了引入AOP依赖包后,不需要去做其他配置。AOP的默认配置属性中,spring.aop.auto属性默认是开启的,也就是说只要引入了AOP依赖后,默认已经增加了@EnableAspectJAutoProxy,不需要在程序主类中增加@EnableAspectJAutoProxy来启用。

编写切面代码

切面类使用@Aspect标注,必须加 @Component,使得切面类注入IOC容器管理

@Aspect
@Component
@Slf4j
public class TestLog {


@Pointcut("execution(* com.yuntian.example.controller.*.*(..))")
public void testLog() {
}


/**
 * 前置通知,方法执行之前执行
 * @param jp
 */
@Before("testLog()")
public void doBefore(JoinPoint jp) {
    // ...
    log.info("方法执行前:.............");
}

/**
 * 后置通知,方法执行之后执行(不管是否发生异常)
 * @param jp
 */
@After("testLog()")
public void doAfter(JoinPoint jp) {
    // ...
    log.info("方法执行后:.............");
}


/**
 * 返回通知,方法正常执行完毕之后执行
 * @param jp
 */
@AfterReturning("testLog()")
public void doAfterReturning(JoinPoint jp) {
    // ...
    log.info("方法执行后返回通知:.............");
}

/**
 * 异常通知,在方法抛出异常之后执行
 * @param jp
 * @param e
 */
@AfterThrowing(value="testLog()",throwing="e")
public void doAfterThrowing(JoinPoint jp,Exception e) {
    // ...
    log.info("方法执行后异常:.............");
}

}
复制代码

业务代码

package com.yuntian.example.controller;

import com.yuntian.example.base.Result;
import com.yuntian.example.entity.dto.OrderDTO;
import com.yuntian.example.entity.vo.OrderVO;
import com.yuntian.example.service.OrderService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author yuntian.
 * @date Created in 18:13 2019/8/7
 * @description
 */
@RestController
@RequestMapping("order")
public class OrderController {


@Resource
private OrderService orderService;


@PostMapping("/createOrder")
public Result createOrder(OrderDTO dto){
   OrderVO orderVO= orderService.createOrder(dto);
    Result<OrderVO> result=new Result<>();
    result.setData(orderVO);
    result.setCode(99);
    return result;
}
}
复制代码

结果

AOP系列(二) Spring AOP

可以看到切面类,实现逻辑同时,而对业务代码毫无侵入。

编写切面代码,使用环绕通知

@Aspect
@Component
@Slf4j
public class TestLogAround {


@Pointcut("execution(* com.yuntian.example.controller.*.*(..))")
public void testLogAround() {
}

/**
 * 使用环绕通知
 * @param pjp
 * @return
 */
@Around("testLogAround()")
public Object doAround(ProceedingJoinPoint pjp){
    Object obj=null;
    try{
        log.info("前置通知:执行之前");
        obj=pjp.proceed();
        log.info("返回通知:执行之后");
    } catch(Throwable e){
        log.info("异常通知:........!");
    }
    return  obj;
}
}
复制代码

结果

AOP系列(二) Spring AOP

编写切面代码,配合自定义注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MTransaction {

@AliasFor("transactionManager")
String value() default "";

@AliasFor("value")
String transactionManager() default "";


int timeout() default -1;

boolean readOnly() default false;

Class<? extends Throwable>[] rollbackFor() default {};

String[] rollbackForClassName() default {};

Class<? extends Throwable>[] noRollbackFor() default {};

String[] noRollbackForClassName() default {};
}



@Component
@Slf4j
@Aspect
public class TransactionAspect {

@Pointcut("@annotation(com.yuntian.example.annotation.MTransaction)")
public void transactionAspect() {
}

/**
 * 使用环绕通知
 *
 * @param pjp
 * @return
 */
@Around("transactionAspect()")
public Object doAround(ProceedingJoinPoint pjp) {
    //获得执行方法的类名
    MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
    Method method = methodSignature.getMethod();
    Object[] args= pjp.getArgs();
    Object obj = null;
    try {
        log.info("前置通知:开启事务...");
        MTransaction transaction = method.getAnnotation(MTransaction.class);
        if (transaction != null) {
            log.info("注解信息:" + transaction.value());
        }
        log.info("参数:"+JSON.toJSONString(args));
        obj = pjp.proceed();
        log.info("返回通知:关闭事务...");
    } catch (Throwable e) {
        log.info("异常通知:事务回滚...");
    }
    return obj;
}

}
复制代码

结果

AOP系列(二) Spring AOP

二、切面介绍

切点表达式

切入点是范围内的所有类的方法

@Pointcut("execution(* com.yuntian.example.controller.*.*(..))")
复制代码

切入点是注解的方法

@Pointcut("@annotation(com.yuntian.example.annotation.MTransaction)")
复制代码
原文  https://juejin.im/post/5db1a353f265da4d1c699492
正文到此结束
Loading...