Spring AOP系列学习笔记一:AOP简介

原文地址程序员囧辉大佬


AOP系列文章链接地址

Spring AOP系列学习笔记一:AOP简介
Spring AOP系列学习笔记二:AOP入口分析
Spring AOP系列学习笔记三:AOP注解原理分析
Spring AOP系列学习笔记四:AOP具体调用流程分析

一、AOP常见概念

Joinpoint(连接点):在系统运行之前,AOP 的功能模块都需要织入到具体的功能模块中。要进行这种织入过程,我们需要知道在系统的哪些执行点上进行织入过程,这些将要在其之上进行织入操作的系统执行点就称之为 Joinpoint,最常见的 Joinpoint 就是方法调用

Pointcut(切点):切点有有助于缩小切面所通知的连接点的范围,指定一组Joinpoint,定义了Advice发生的地方,例如:execution(* com.zgf.proxy.ProductImpl.*(…)).

Advice(通知/增强):定义了将会织入到Joinpoint的具体逻辑,通过注解 @Before、@After、@Around 来区别在 JointPoint 之前、之后还是环绕执行的代码。

Aspect(切面):Aspect 是对系统中的横切关注点逻辑进行模块化封装的 AOP 概念实体。类似于 Java 中的类声明,在 Aspect 中可以包含多个 Pointcut 以及相关的 Advice 定义。

Weaving(织入):织入指的是将 Advice 连接到 Pointcut 指定的 Joinpoint 处的过程,也称为:将 Advice 织入到 Pointcut 指定的 Joinpoint 处。

Target(目标对象):符合 Pointcut 所指定的条件,被织入 Advice 的对象。

一个简单的使用

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
 
@Component
@Aspect
public class AopAspect {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(AopAspect.class);
 
    @Pointcut("execution(* com.joonwhee.open.demo.service..*.*(..))")
    public void pointcut() {
    }
 
    @Before("pointcut()")
    public void before() {
        LOGGER.info("before advice");
    }
 
    @After("pointcut()")
    public void after() {
        LOGGER.info("after advice");
    }
 
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws InterruptedException {
        System.out.println("around advice start");
        try {
            Object result = proceedingJoinPoint.proceed();
            System.out.println("result: " + result);
            System.out.println("around advice end");
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return null;
        }
    }
}

实现机制

SpringAOP实现代理模式有两种方式:
CGLIB动态代理与JDK动态代理区别

  1. java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
  2. 而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

JDK动态代理

public class MyInvocationHandler implements InvocationHandler {
 
    private Object origin;
 
    public MyInvocationHandler(Object origin) {
        this.origin = origin;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("invoke start");
        Object result = method.invoke(origin, args);
        System.out.println("invoke end");
        return result;
    }
}
 
 
public class JdkProxyTest {
    public static void main(String[] args) {
        UserService proxy = (UserService) Proxy.newProxyInstance(JdkProxyTest.class.getClassLoader(),
                new Class[]{UserService.class}, new MyInvocationHandler(new UserServiceImpl()));
        proxy.doSomething();
    }
}

CGLIB 代理

public class CglibInterceptor implements MethodInterceptor {
 
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("intercept start");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("intercept end");
        return result;
    }
}
 
public class CglibProxyTest {
 
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(CglibObject.class);
        enhancer.setCallback(new CglibInterceptor());
        CglibObject proxy = (CglibObject) enhancer.create();
        proxy.doSomething();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值