【Spring】基于注解的AOP(面向切面编程)

AOP(Aspect Oriented Programming),即面向切面编程(也叫面向方面编程,面向方法编程)。其主要作用是,在不修改源代码的情况下给某个操作添加额外的功能。像日志记录,事务处理,权限控制,都可以用AOP来“优雅”地实现,使这些额外功能和真正的业务逻辑分离开来,软件的结构将更加清晰。

Spring AOP是基于代理机制的,通过JDK Proxy和CGLIB Proxy两种方法实现代理。
1)如果target object没有实现任何接口,那么Spring将使用CGLIB来实现代理。CGLIB是一个开源项目,它是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。
2)如果target object实现了一个以上的接口,那么Spring将使用JDK Proxy来实现代理,因为Spring默认使用的就是JDK Proxy,并且JDK Proxy是基于接口的。这也是Spring提倡的面向接口编程。

依赖jar
 

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

下面是一个简单的示例:

1.定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
    String type();
}

2.AOP配置

@Aspect
@Component
public class AOPConfig {

    @Around(value = "@annotation(OperationLog)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("方法环绕begin...参数:"+Arrays.toString(proceedingJoinPoint.getArgs()));
        try {
            Object ret= proceedingJoinPoint.proceed();
            System.out.println("方法环绕end...结果:"+ret);
            return ret;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }

    @Before(value = "@annotation(OperationLog)")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes requestAttributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest req= requestAttributes.getRequest();
        System.out.println("uri:"+req.getRequestURI());
        System.out.println("执行方法前 : " + Arrays.toString(joinPoint.getArgs()));
    }

    @After(value = "@annotation(OperationLog)")
    public void after(JoinPoint joinPoint){
        System.out.println("执行方法后:"+ Arrays.toString(joinPoint.getArgs()));
    }

    @AfterReturning(pointcut = "@annotation(OperationLog)",returning = "ret")
    public void doAfterReturning(Object ret){
        System.out.println("方法的返回值 : " + ret);
    }

    @AfterThrowing(pointcut = "@annotation(OperationLog)",throwing = "ex")
    public void AfterThrowing(JoinPoint joinPoint,Throwable ex){
        System.out.println("方法执行异常 : " + ex);
    }
}

3.服务类

@RequestMapping("/aop")
@RestController
public class AOPCtrl {

    @Autowired
    private MessageService messageService;

    @RequestMapping(value = "/test",method = RequestMethod.GET)
    public String test(){
        return messageService.sendMessage("xiaoming",29);
    }
}

@Service
public class MessageService {

    @OperationLog(type = "sendMessage")
    public String sendMessage(String name,int age){
        return "this person: "+name+" age: "+age;
    }
}

运行结果:
方法环绕begin...参数:[xiaoming, 29]
uri:/aop/test
执行方法前 : [xiaoming, 29]
方法环绕end...结果:this person: xiaoming age: 29
执行方法后:[xiaoming, 29]
方法的返回值 : this person: xiaoming age: 29

本文转载自:https://www.jianshu.com/p/9b8a8191a727

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值