3、spring详解-spring aop

一、简介

        spring AOP⾯向切⾯编程,实则是⼀种思想,是对某类事物的集中处理。通俗来讲,将与核心业务无关的代码独立抽取出来,形成一个独立的组件,然后以横向交叉的方式应用到业务流程当中的一种操作理念。

二、spring AOP组成

        1、切面(Aspect)

        切面通常由切点和通知组成。是独立出来增强功能的集合。

        2、连接点(Join Point)

        应⽤执⾏过程中能够插⼊切⾯的⼀个点,相当于需要被增强的某个 AOP 功能的所有⽅法。

        3、通知(Advice)

        相当于需要增强的内容。有五种类型:

  •  前置通知使⽤ @Before:通知⽅法会在⽬标⽅法调⽤之前执⾏。
  • 后置通知使⽤ @After:通知⽅法会在⽬标⽅法返回或者抛出异常后调⽤。
  • 返回之后通知使⽤ @AfterReturning:通知⽅法会在⽬标⽅法返回后调⽤。
  • 抛异常后通知使⽤ @AfterThrowing:通知⽅法会在⽬标⽅法抛出异常后调⽤。
  • 环绕通知使⽤ @Around:通知包裹了被通知的⽅法,在被通知的⽅法通知之前和调⽤之后执⾏⾃定义的⾏为。

        4、切点(Pointcut )

        提供⼀组规则,来匹配 Join Point,给满⾜规则的 Join Point 添加 Advice。相当于保存了众多连接点的⼀个集合

三、使用示例

        1、被增强类

@RestController
@RequestMapping("/aopTest")
public class AopTestController {

    @GetMapping("test")
    public void insert() {

        System.out.println("实际逻辑。。。。。。。。。");
    }
}

        2、增强类

@Aspect
@Component
public class AopComponent {


    @Pointcut(value = "execution(* com.example.testaop.controller.AopTestController.*(..))")
    public void pointCut(){
    }

    @Before(value = "pointCut()")
    public void before(){
        System.out.println("aop增强测试。。。。before。。。。");
    }

    @After(value = "pointCut()")
    public void after(){
        System.out.println("aop增强测试。。。。。after。。。");
    }

    @Around(value = "pointCut()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("aop增强测试。。。。。around1。。。");
        joinPoint.proceed();
        System.out.println("aop增强测试。。。。。around2。。。");

    }

    @AfterReturning(value = "pointCut()")
    public void afterReturning(){
        System.out.println("aop增强测试。。。。。afterReturning。。。");
    }

    @AfterThrowing(value = "pointCut()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e){
        System.out.println("aop增强测试。。。。。afterThrowing。。。");
        System.out.println("throwing: "+e.getMessage());
    }
}

        3、测试结果

aop增强测试。。。。。around1。。。
aop增强测试。。。。before。。。。
实际逻辑。。。。。。。。。
aop增强测试。。。。。afterReturning。。。
aop增强测试。。。。。after。。。
aop增强测试。。。。。around2。。。

        4、结论

通知的顺序  around -> before -> 实际方法 -> afterReturning -> after -> around

四、spring AOP实现原理

        spring AOP是基于动态代理实现的。支持 JDK Proxy 和 CGLIB 两种方式。

        1、jdk动态代理

         主要由重写InvocationHandle接口的invoke方法和Proxy创建代理实例构成。

        1.1、接口

public interface JdkProxy {

    void testJdkProxy();
}

        1.2、实现

public class JdkProxyImpl implements JdkProxy {

    @Override
    public void testJdkProxy() {

        System.out.println("对JdkProxy的实现。。。。。JdkProxyImpl。。。。");
    }
}

        1.3、动态代理处理类

public class MyInvcationHandler implements InvocationHandler {

    private Object object;

    public MyInvcationHandler( Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("MyInvcationHandler代理1。。。。。invoke。。。。");
        method.invoke(object,args);
        System.out.println("MyInvcationHandler代理2。。。。。invoke。。。。");

        return null;
    }
}

        1.4、测试

@GetMapping("test1")
public void test1() {

    JdkProxyImpl jdkProxyImpl = new JdkProxyImpl();
    MyInvcationHandler myInvcationHandler = new MyInvcationHandler(jdkProxyImpl);

    JdkProxy jdkProxy = (JdkProxy) Proxy.newProxyInstance(jdkProxyImpl.getClass().getClassLoader(),
            jdkProxyImpl.getClass().getInterfaces(), myInvcationHandler);
    jdkProxy.testJdkProxy();

}

        1.5、结论

MyInvcationHandler代理1。。。。。invoke。。。。
对JdkProxy的实现。。。。。JdkProxyImpl。。。。
MyInvcationHandler代理2。。。。。invoke。。。。

        2、cglib动态代理

         重写需被增强类的方法,子类通过传递方法拦截器Methodlnterceptor实现方法拦截,并在intercept中做具体增强。

        2.1、cglib增强

public class CglibProxyImpl implements MethodInterceptor {

    private Object object;

    public Object getInstance(Object object) {

        this.object = object;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.object.getClass());
        // 设置回调方法
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("cglib增强1。。。。。intercept。。。。。");
        methodProxy.invokeSuper(o,objects);
        System.out.println("cglib增强2。。。。。intercept。。。。。");
        return null;
    }
}

        2.2、测试

@GetMapping("test2")
public void test2() {

    CglibProxyImpl cglibProxy = new CglibProxyImpl();
    JdkProxyImpl cglibProxyInstance = (JdkProxyImpl) cglibProxy.getInstance(new JdkProxyImpl());
    cglibProxyInstance.testJdkProxy();
}

        2.3、结论

cglib增强1。。。。。intercept。。。。。
对JdkProxy的实现。。。。。JdkProxyImpl。。。。
cglib增强2。。。。。intercept。。。。。

        3、两者区别

        jdk代理适用于代理接口类型的;cglib代理适用于代理类类型的。

        jdk代理基于Java反射机制实现;cglib不是。

        jdk代理无需引用第三方库,jdk自带;cglib需要依赖

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值