spring AOP面向切面编程
什么是spring AOP
要说什么是spring AOP 我们就必须要介绍什么是代理模式:代理模式是 二十三种设计模式中的一种,属于结构型模式。它的作用就是通过提供一个代理类,让我们在调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来——解耦。调用目标方法时先调用代理对象的方法,减少对目标方法的调用和打扰,同时让附加功能能够集中在一起也有利于统一维护。
举个例子: 比如租房子的时候,我们找的中介,他就是我和房东的代理,我和房东是经过中介来交流的。
代理分为两种:静态代理和动态代理。
静态代理
就是我们自己创建一个代理类,在代理类里面写入我们需要代理的实例,在这个代理类中完成我们需要代理的操作,比如日志的输出等。
优点:简单易懂,可以完成我们需要代理类的目的(解耦)
缺点:由于代码都写死了,没有灵活性,在我们需要输出在其他类中相同的日志时,我们就需要再声明多个静态代理类,虽然内容相同,但是这样就会使代码量大大增加,后期的维护工作也会变得复杂
动态代理
动态代理是一种在运行时动态创建代理类的机制,它可以在运行时为接口或类生成代理实例,而无需在编译时就预先创建特定的代理类。 它与静态代理的原理是差不多的,是不过静态代理是我们手动去创建代理类的,而动态代理是 通过java.lang.reflect.Proxy
类和 java.lang.reflect.InvocationHandler
接口实现的,是自动的把我们需要的代理对象加入到被代理类中的。
优点:可以减少重复代码,只需编写一个通用的代理类即可代理多个类或接口,同时也提高了代码的灵活性和可扩展性。
缺点:相比静态代理,动态代理的实现复杂一些。
代理总结
代理就是在编码过程中把我们非目标核心代码和目标核心代码分开管理,从而使目标核心代码不受其他代码干扰,
但是我们发现无论使用静态代理还是动态代理,需要编写的代码都还是比较繁琐,都需要自己编写代理工厂。
所以我们就需要spring AOP框架来给我们简化代码;
AOP(面向切面编程)编程思想
AOP是不同与OOP(面向对象编程),它是利用”横切“的思维,将对象解开,将里面重复的公共行为封装到一个可以重用的模块中,就像洋葱一样,一圈一圈的,就像我们的代码,我们从中切开如图一截,这就是我们的公共代码,它贯穿多个对象中,我们要做的就是将它拿出来,封装成一个类,让需要的对象去调用它即可,就可减少我们的代码量和便于维护。
AOP的思想主要可以用于以下场景:
1.日志的记录 2.事物的处理 3.安全控制 4.性能监控 5.异常处理 6.缓存控制 7.动态代理
AOP中的术语
1.横向关注点:就是抽出多个方法中的相同的业务。
2.通知:就是我们横向关注点抽出的业务,需要用方法来实现。
3.连接点:我们需要在目标方法的哪个位置完成切入。
4.切入点:定位连接点的方式,或者可以理解成被选中的连接点。
5.切面(aspect):入点和通知的结合,就是切面。
6.目标(target):需要被代理的对象。
7.代理(proxy): 向目标对象应用通知之后创建的代理对象 。
8.织入(weave): 指把通知应用到目标上,生成代理对象的过程 。
Spring AOP的实现
1.导入关键依赖
<!-- spring-aspects会帮我们传递过来aspectjweaver -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.6</version>
</dependency>
2.准备接口
public interface Calculator {
int add(int i, int j);
}
3.目标核心类
@Component
public class CalculatorPureImpl implements Calculator {
@Override
public int add(int i, int j) {
int result = i + j;
return result;
}
}
4.声明切面类
@Aspect
@Component
public class LogAspect {
@Before(value = "execution(public int com.atguigu.proxy.CalculatorPureImpl.add(int,int))")
public void printLogBeforeCore() {
System.out.println("[AOP前置通知] 方法开始了");
}
}
5.开启aspectj注解支持
xml方式
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="org.example" />
<aop:aspectj-autoproxy />
</beans>
注解方式
@Configuration
@ComponentScan(basePackages = "org.example")
@EnableAspectJAutoProxy
public class Config {
}
6.测试
@SpringJUnitConfig(value = {Config.class})
public class AopTest {
@Autowired
private Calculator calculator;
@Test
public void testCalculator(){
calculator.add(1,1);
}
}
参考于尚硅谷新版SSM框架全套视频教程,Spring6+SpringBoot3最新SSM企业级开发