如何理解 Spring 中的 AOP
Spring 中的 AOP 实现原理
b、实现类:Spring 采用 cglib字节码增强。
a、Aop底层将采用代理机制进行实现 (最底层也是依赖反射) 。
1、对 AOP 的理解(画图解释)
2、AOP 中通过 JDK动态代理简单案例演示
public interface UserService {
void addUser();
void updateUser();
int deleteUser(int id);
}
=========================================================================================
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void updateUser() {
System.out.println("更新用户");
}
@Override
public int deleteUser(int id) {
System.out.println("通过id删除用户");
return 1;
}
}
切面类
public class MyAspect {
public void before(){
System.out.println("开启事务");
}
public void after(){
System.out.println("提交事务");
}
}
public class MyBeanFactory {
// JDK实现动态代理
public static UserService createUserService() {
//1.创建目标对象target
final UserService userService = new UserServiceImpl();
//2.声明切面类对象
final MyAspect aspect = new MyAspect();
//3.把切面类2个方法应用于目标类
//3.1 创建JDK代理,拦截方法
UserService serviceProxy = (UserService) Proxy.newProxyInstance(
MyBeanFactory.class.getClassLoader(),
userService.getClass().getInterfaces(),
(proxy, method, args) -> {
//开启事务
aspect.before();
//方法返回值:业务方法的返回值
Object retObj = method.invoke(userService, args);
//System.out.println("拦截返回值:" + retObj);
//提交事务
aspect.after();
return retObj;
}
);
return serviceProxy;
}
}
public class AOPTest {
public static void main(String[] args) {
UserService userService = MyBeanFactory.createUserService();
userService.deleteUser(1);
userService.addUser();
userService.updateUser();
}
}
开启事务 通过id删除用户 提交事务 <=====================> 开启事务 添加用户 提交事务 <=====================> 开启事务 更新用户 提交事务 <=====================>
从测试结果可以看出,每次在执行业务代码的时候,会拦截对应的方法,执行切面类。
在 debug 测试函数: UserService userService = MyBeanFactory.createUserService(); 可以看出直接得到的是代理对象,代理对象中就有实现的功能。
在 debug 测试函数: UserService userService = new UserServiceImpl(); 可以看出直接得到的是其实现类,没有代理。
感兴趣的同学可以将测试函数中代码替换成上面两种。看看测试结果,以便于更好理解 AOP 思想。
3、AOP 中通过 CGlib 动态代理简单案例演示
public class StudentService {
void delete() {
System.out.println("删除用户");
}
void add() {
System.out.println("添加用户");
}
void update() {
System.out.println("更新用户");
}
}
public class MyBeanFactory {
// CGlib实现代理
public static StudentService createStudentService(){
//1.创建目标对象target
final StudentService studentService = new StudentService();
//2.声明切面类对象
final MyAspect aspect = new MyAspect();
//3.创建增强对象
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(studentService.getClass());
//设置回调【拦截】
enhancer.setCallback((MethodInterceptor) (proxy, method, args, methodProxy) -> {
aspect.before();
Object retObj = methodProxy.invokeSuper(proxy,args);//解藕
System.out.println("拦截.....");
aspect.after();
return retObj;
});
//创建代理对象
StudentService serviceProxy = (StudentService) enhancer.create();
//System.out.println("serviceProxy);
return serviceProxy;
}
}
public class AOPTest {
public static void main(String[] args) {
StudentService studentService = MyBeanFactory.createStudentService();
studentService.add();
System.out.println("<=====================>");
studentService.delete();
System.out.println("<=====================>");
studentService.update();
System.out.println("<=====================>");
}
}
开启事务 添加用户 拦截..... 提交事务 <=====================> 开启事务 删除用户 拦截..... 提交事务 <=====================> 开启事务 更新用户 拦截..... 提交事务 <=====================>
a、没有接口,只有实现类。 b、采用字节码增强框架 cglib,在运行时 创建目标类的子类,从而对目标类进行增强。