Aop也就是面向切面编程,所谓面向切面编程,只是一个吊炸天的术语罢了,本质不难理解。
我们先来假设一个业务流程:
我们有三个类,每个类都是一个角色,我们每次都需要在使用角色前先记录当前时间,使用角色后释放数据库,那么我们要怎么做?难道是每个类中都重复写一遍吗?还是我们写一个类,然后继承它?这是一个办法,但是耦合度太高了,结合之前我们的动态代理,就可以较为轻松的解决这个问题。
因此所谓的Aop就是把一些大家都用的到的方法,写到代理类中,然后增强它就可以了。
我们来给出一个实例就比较好动。
首先是spring中要用Aop,我们需要引入一个jar包--->AspectJ
我们首先要在项目中引入这个包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.0-M2</version>
</dependency>
然后我们创建一个普通类
@Service("huiliyi")
public class Huiliyi {
public void print(){
System.out.println("绘梨衣的");
}
}
请注意,我们此时还需要引入
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
一个用来注释开发的jar包
然后我们需要编写代码增强类,也就是我们需要写代理类,并且需要在代理类中使用目标类的方法
@Aspect
@Component("huiAspect")
public class huiAspect {
// 要写切点表达式 execution( 修饰符 返回值类型 全限定类名 方法名(形式参数) 异常 ) * .. 表示全部匹配
@Before("execution(* org.example.service.com.Huiliyi.*(..))")
public void beforee(){
System.out.print("可爱的");
}
}
请注意 这里代理类的写法采用切点表达式--->切点表达式的写法较为特殊
然后我们需要将这两个类注册到spring容器当中,可以采用bean.xml的方式注册,也可以使用全部注解的方式开发,我们选择全部注解的方式开发
@Configuration
@ComponentScan({"org.example.service.com"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Config {
}
我们需要写一个类 然后使用 @Configuration 告诉spring容器这是配置类 @ComponentScan({"org.example.service.com"}) 告诉spring容器扫描那个包,来获得注解,这是之前章节的一部分(本文跟着B站动力节点老杜的Spring6记录)@EnableAspectJAutoProxy(proxyTargetClass = true)告诉Spring容器我们选择c..什么的动态代理,没有选择jdk自带的,jdk自带的只能对接口进行动态代理,这个可以对接口也可以对类
然后我们完成测试类
public class tee {
@Test
public void testaspect(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class) ;
Huiliyi huiliyi = applicationContext.getBean("huiliyi",Huiliyi.class);
huiliyi.print();
}
}
就可以输出结果了。
当然切面的编写还有很多,有后置切面 写法都是在 切面类中添加方法 采用不同的注解 来完成对应的功能 不在记录了。