Spring AOP学习

AOP 概念了解

AOP(Aspect Oriented Programming)面向切面编程,是针对面向对象编程的一种补充,同时也是spring中第二个最核心的功能,例如可以进行权限认证,日志输出等,可以无侵入的对原来的功能进行切面加入自定义的非业务功能。

  • 切面(AspectJ):对横切关注点的抽象
  • 连接点(Joinpoint):被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
  • 通知(Advice):AOP框架在特定的切入点执行的增强处理,分为前置、后置、异常、最终、环绕五种情况
  • 切入点(Pointcut):需要拦截的点
  • 引入:将方法或字段添加到被处理的类中。Spring允许引入新的接口到任何被处理的对象。例如,你可以使用一个引入,使任何对象实现IsModified接口,以此来简化缓存
  • 目标对象:被AOP框架进行增强处理的对象,也被称为被增强的对象
  • AOP代理:AOP框架创建的对象,简单的说,代理就是对目标对象的加强。Spring中的AOP代理可以是JDK动态代理,也可以是CGLIB代理
  • 织入(Weaving):将增强处理添加到目标对象中,并创建一个被增强的对象的过程。

在spring中AOP代理对象依旧是由IOC容器管理着,在具体代理生成中可以由java动态代理生成也可以由cglib字节码增强完成,具体运行中会根据具体情况选择合适的代码生成方式。如果是接口,则只会使用动态代理生成
在了解完AOP的基础知识后,介绍AOP的两种使用方法,XML配置和注解

XML 配置





   
   
       
       
       
       
       
   

public class PeopleAop {

    public void before(){
        System.out.println("before");
    }

    public void after(){
        System.out.println("after");
    }

    public Object around(ProceedingJoinPoint pj){

        System.out.println("around before");
        Object obj = null;
        try {
            obj = pj.proceed();
        } catch (Throwable throwable) {

        }
        System.out.println("around after");
        return obj;
    }

    public void afterReturn(){
        System.out.println("after return");
    }

    public void excep(){
        System.out.println("error!!!!");
    }

}

public class People {
    public void say() {
        System.out.println("chinese");
    }
}

最后的执行结果


Spring AOP学习_第1张图片
image.png

看图得出先后顺序是before、around、after、after return。但是xml配置的执行顺序就真的是这样的么?

当我把上面xml配置的before和around换一个位置之后输出到结果

Spring AOP学习_第2张图片
image.png

结果发生了变化,成为了around、before、after、after return

注解







// 接口类
public interface Animal {
    void sleep(String name);
}

// 实现类
public class AnimalImpl implements Animal {

    public AnimalImpl() {
        System.out.println("init");
    }

    public void sleep(String name) {
        System.out.println(name + " sleep");
    }
}

// 切面类
public class AnimalAop {

    @Pointcut("execution(* com.demo.Aop.*.*(..))")
    public void pointCut(){}
    // 定义一个切点,会选择com.demo.Aop下面所有的类

    @Around("pointCut() && args(name)")
    public Object around(ProceedingJoinPoint pj, String name){
        // 定义为around注解,添加了切点,并且同时加上了参数
        Object obj = null;
        System.out.println(name + " around before");
        try {
            obj = pj.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println(name + " around after");
        return obj;
    }

    @Before("pointCut() && args(name)")
    public void before(String name){
        System.out.println(name + " animal before");
    }

    @After("execution(* com.demo.Aop.*.*(..))")
    public void after(){
        // 这个直接使用了execution,而没有使用已经定义好的切点
        System.out.println("animal after");
    }
    
}

执行结果


Spring AOP学习_第3张图片
image.png

在原本的实现类实现之后,执行的先后顺序为around、before、after、after return
不过这里是没有XML注解的那种先后执行顺序,所有的执行顺序都是由spring自身决定的

在当前的demo中可能注意到了,所使用的AnimalImpl是继承自Animal接口的,如果改成没有接口的情况呢?

Spring AOP学习_第4张图片
image.png
Spring AOP学习_第5张图片
image.png

很明显 在使用接口的时候,spring会使用java的动态代理实现,否则会使用cglib实现代理功能

demo基本上就完成了,后面的学习文章会具体分析XML配置和注解配置的实现细节以及同异

你可能感兴趣的:(Spring AOP学习)