Spring_202311_21_2 2. AOP面向切面编程
AOP:全称是 Aspect Oriented Programming 即:面向切面编程。
简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。
即当需要扩展功能时,传统方式采用纵向继承方式实现。但这种方式有很多缺点。 比如:父类方法名称改变时,子类也要修改。给多个方法扩展功能时,子类也需要修改。 因此,spring的AOP,实际上是采用横向抽取机制,取代传统的纵向继承体系。
- AOP术语
a) 通知、连接点、切入点、切面、引入、目标 等 - AOP =>JDK动态代理的方式
a) 需求:在每个方法执行前输出“此方法开始运行”,在每个方法之后输出“此方法运行结束”
b) 具体操作步骤:
- 创建目标类:UserService/UserServiceImpl
package com.bboy.service.impl;
import com.bboy.service.UserService;
/**
* @类描述:
* @作者:秦帅
* @时间:2023/11/21 0021 11:31:52
*/
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("===========>addUser");
}
@Override
public void updateUser() {
System.out.println("===========>updateUser");
}
@Override
public void deleteUser() {
System.out.println("===========>deleteUser");
}
}
- 创建切面类:MyLogAspect
package com.bboy.aspect;
/**
* @类描述:
* @作者:秦帅
* @时间:2023/11/21 0021 11:39:45
*/
public class MyLogAspect {
public void methodsBefore(){
System.out.println("===========>此方法开始执行");
}
public void methodsAfter(){
System.out.println("===========>此方法执行结束");
}
}
- 创建代理类:(目标类与切面类进行结合)
package com.bboy.factory;
//-将目标类与切面类结合
import com.bboy.aspect.MyLogAspect;
import com.bboy.service.UserService;
import com.bboy.service.impl.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @类描述:
* @作者:秦帅
* @时间:2023/11/21 0021 11:45:12
*/
public class MyAspectFactory {
//-: 获取结合之后的目标类
public static UserService createService() {
// -1. 目标类
final UserService userService = new UserServiceImpl();
// -2. 切面类
MyLogAspect myLogAspect = new MyLogAspect();
// -3. jdk动态代理的形式,将目标类与切面类进行结合
return (UserService) Proxy.newProxyInstance(
MyLogAspect.class.getClassLoader(), //-当前类
userService.getClass().getInterfaces(),//-目标类
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//-: 前执行(调用切面类的方法)
myLogAspect.methodsBefore();
//-: 执行目标类的方法
Object obj = method.invoke(userService, args);
//-: 后执行(调用切面类的方法)
myLogAspect.methodsAfter();
return obj;
}
}
);
}
}
- 创建测试类
package com.bboy.demo;
import com.bboy.factory.MyAspectFactory;
import com.bboy.service.UserService;
/**
* @类描述:
* @作者:秦帅
* @时间:2023/11/21 0021 12:05:30
*/
public class Demo {
public static void main(String[] args) {
UserService userService = MyAspectFactory.createService();
userService.addUser();
userService.deleteUser();
userService.updateUser();
}
}
- 运行结果