Spring使用@AspectJ开发AOP(零配置文件)

前言:

 AOP并不是Spring框架特有的。Spring只是支持AOP编程 (面向切面编程) 的框架之一。

概念:

1、切面(Aspect)

  一系列Advice + Pointcut 的集合。

2、通知(Advice)

  通知是切面开启后,切面的方法。

  • 前置通知 ( before ):在动态代理反射原有对象方法 或者 执行环绕通知 前 执行的通知功能
  • 后置通知(after):在动态代理反射原有对象方法 或者 执行环绕通知 后 执行的通知功能
  • 返回通知 (afterReturning):在动态代理反射原有对象方法 或者 执行环绕通知 后 正常返回(无异常)执行的通知功能
  • 异常通知(afterTherowing):在动态代理反射原有对象方法 或者 执行环绕通知 产生异常后执行的通知功能
  • 环绕通知(around):在动态代理中,它可以取代当前被拦截对象的方法,提供回调原有被拦截对象的方法

3、引入(Introduction)

  引入允许我们在现有的类里添加自定义的类和方法

4、切点(Pointcut)

  这是一个告诉Spring AOP 在什么时候启动拦截并织入对应的流程,因为并不是所有的开发都是需要启动AOP的,它往往通过正则表达进行限定

5、连接点( join point)

  Pointcut 中的某个具体位置。

首先要有 AspectJ 的依赖 

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.2</version>
</dependency>

现在我们去创建一个Cat 类 (目标类)出来,并使用@Component 注入容器中

import org.springframework.stereotype.Component;

//目标类
@Component
public class Cat {

    public void eat(){
        System.out.println("小白猫,开始吃鱼了!!!!");
    }
}

然后再创一个 切面类 出来

@Component
@Aspect
public class CatAdvice {//切面类


    //execution (* *.*(..) )
    // 第一个* 代表着 返回类型是任意的
    // 第二个* 代表着 类的全限定名 * 代表着所有
    // *(..) 代表着 任意方法 任意的参数
    // 比如  execution ( void com.oukele.learning.aop2.Cat.eat())
    
    //切点
    @Pointcut("execution(* *.*(..))")
    public void pointcut(){};

    @Before("pointcut()")
    public void clean(){//在猫吃之前执行的方法 ,把鱼清洗一下 (前置通知)
        System.out.println("现在我们把我这条鱼,清洗一下");
    }

    @After("pointcut()")
    public void  tidy(){//猫吃完鱼后执行的方法,收拾一下剩下的残渣 (后置通知)
        System.out.println("收拾,小白猫吃剩下来的残渣。!!!");
    }

}

再创一个配置类

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration//声明当前类是配置类 ( 类似于 xml 文件一样 )
@ComponentScan(basePackages = "com.oukele.learning.aop2")//扫描某个包中的注解
@EnableAspectJAutoProxy//激活 代理功能
public class SpringConfig {

}

现在开始测试啦

public class Main {
    public static void main(String[] args) {
        //加载配置类
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        //从容器中获取Cat类
        Cat cat = context.getBean(Cat.class);
        cat.eat();//调用Cat类的方法

    }
}

结果:

1 现在我们把我这条鱼,清洗一下
2 小白猫,开始吃鱼了!!!!
3 收拾,小白猫吃剩下来的残渣。!!!

 只要我们把切面类里面的@Componet去掉,就会发现,这只猫,是直接吃鱼的。

这就是面向切面编程。。。。

代码示例下载:https://github.com/oukele/Spring-AspectJ-Annotion

原文地址:https://www.cnblogs.com/oukele/p/10137958.html