一、进入SpringAop的世界(什么是Aop?)
AOP (Aspect Orient Programming),直译过来就是 面向切面编程。AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。
二、为什么要用它?
- 我们来画图理解一下(画的丑能看就行哈,各位别介意):
1.传统的OOP开发逻辑
可以看见这个逻辑很干净,但是想象一下下面场景,有一天,新增了一个需求,需要再做出修改,我们需要再抽象出一个方法,然后再在需要的地方分别调用这个方法,又或者我们不需要这个方法了,我们还是得删除掉每一处调用该方法的地方。是不是很麻烦!这个时候Aop就可以很好的去解决。
2.利用Aop增加功能
如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,AOP保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能。
三、怎么用它?
AOP术语:
- 通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
- 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
- 切点(PointCut): 可以插入增强处理的连接点。
- 切面(Aspect): 切面是通知和切点的结合。
- 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
- 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。
说了怎么多大家可能还是有点迷糊,接下来举个例子
四、举例通过注解方式使用SpringAOP
- 创建好一个springBoot项目 在已有的依赖添加依赖
<!--spring 面向切面 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
- 做准备工作,创建好包和包下接口与类(我们是模拟所以就不是很规范)
- User类
//lombok注解
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private Integer account;//账号
private String password;//密码
}
- UserService
public interface UserService {
//模拟登录业务方法
User login(User user);
}
- UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
//登录
@Override
public User login(User user) {
return user;
}
}
- 接下来我们有这样一个需求,需要在用户登录后我们能够打印:某某登录
- 编写切面
- LogAop类
@Component //定义一个组件 放入Ioc容器
@Aspect //定义一个切面类
public class LogAop {
/**
* 定义横切点 定义切入点表达式
*/
@Pointcut("execution(* com.demoaop.service.UserService.login(..))")
private void pointcut(){
}
/**
* 切入点 方法执行之前
* @param joinPoint
*/
@Before(value = "pointcut()")
public void before(JoinPoint joinPoint){
System.out.println("========前置通知=========");
Object[] args = joinPoint.getArgs();
System.out.println(joinPoint.getSignature().getName()+"执行前...");
for (Object arg : args) {
System.out.println(joinPoint.getSignature().getName()+"参数为"+arg);
}
}
/**
* 执行方法后 returning=返回值名
* @param joinPoint
* @param o
*/
@AfterReturning(value = "pointcut()",returning = "o")
public void afterReturning(JoinPoint joinPoint, Object o){
System.out.println("========后置通知=========");
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName+"方法执行后...");
System.out.println("返回值为:"+ o);
}
}
- 在测试类进行测试
- DemoAopApplicationTests测试类
@SpringBootTest
class DemoAopApplicationTests {
//自动装配service
@Autowired
private UserService service;
@Test
public void testOne(){
//执行登录方法
service.login(new User(2020001,"123456"));
}
}
- 可以看见这里只执行登录方法,并没有做其他的操作,但是我们刚才写了一个切面类,横切这个方法了
- 运行结果