Spring系列教程——11编程实现AOP
程序员文章站
2022-12-02 15:43:31
Spring系列教程——11编程实现AOP...
Spring系列教程——11编程实现AOP
在开始本章之前,需要先理解上一节讲解的这一张图片。
一.JDK动态代理实现
上一章我们讲到了,JDK动态代理实现对应的是接口+实现类
先创建一个切面类MyAspect:
package aspect;
public class MyAspect {
public void before(){
System.out.println("before被执行了");
}
public void after(){
System.out.println("after被执行了");
}
}
接口IUserService:
package service;
public interface IUserService {
void addUser();
void deleteUser();
void updateUser();
}
实现类UserServiceImpl:
package service;
public class UserServiceImpl implements IUserService {
@Override
public void addUser() {
System.out.println("添加User");
}
@Override
public void deleteUser() {
System.out.println("删除User");
}
@Override
public void updateUser() {
System.out.println("更新User");
}
}
现在我们需要做的就是把切面类MyAspect的advice织入到UserServiceImpl的方法当中。那么具体就是获取UserServiceImpl的代理类来实现。
我们先创建一个工厂类来实现
public class UserServiceFactory {
public static IUserService createUserService(){
IUserService userService = (IUserService) Proxy.newProxyInstance(UserServiceFactory.class.getClassLoader(), UserServiceImpl.class.getInterfaces(), new InvocationHandler() {
@Override
//proxy是代理,method是在实际调用方法时反射产生的,args是对应的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MyAspect myAspect = new MyAspect();
myAspect.before();
Object retObj = method.invoke(new UserServiceImpl(), args);
myAspect.after();
return retObj;
}
});
return userService;
}
}
newProxyInstance参数讲解:
ClassLoader loader, 类加载器,写当类
Class<?>[] interfaces, 接口,接口的方法会被拦截
InvocationHandler h 处理
测试代码:
IUserService userService = UserServiceFactory.createUserService();
userService.addUser();
System.out.println("-----");
userService.deleteUser();
System.out.println("-----");
userService.updateUser();
System.out.println("-----");
二.CGLIB实现
上一章我们讲到了,CGLIB实现动态代理对应的是只有类,没有接口
具体的原理就是:采用字节码增强框架 cglib(需要导包),在运行时 创建目标类的子类,从而对目标类进行增强。
jar包分享:
链接:https://pan.baidu.com/s/1J66jrMWMAdZCVCOGn6F33A
提取码:lzmd
在JDK代理的基础上我们对工厂类进行修改:
public class UserServiceFactory {
public static IUserService createUserService(){
//目标类
final IUserService userService = new UserServiceImpl();
//切面类
MyAspect myAspect = new MyAspect();
//增强类
Enhancer enhancer = new Enhancer();
//由于原理是实现目标类的子类来进行扩展
enhancer.setSuperclass(userService.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
//o是代理对象为UserServiceImpl的子类,method是对应调用的增强方法,objects是参数,methodProxy是代理方法
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
myAspect.before();
method.invoke(userService,objects);
methodProxy.invokeSuper(o,objects);
myAspect.after();
return null;
}
});
return (IUserService) enhancer.create();
}
我们发现
method.invoke(userService,objects);
methodProxy.invokeSuper(o,objects);
上面两种方式都成功执行了,但是第二种方式更好因为实现了解耦的效果,而第一个却使用到了外面的userService这个类。
上一篇:Spring系列教程——10AOP概述与原理
下一篇:Spring系列教程——12配置文件实现AOP
本文地址:https://blog.csdn.net/qq_44932835/article/details/107572300
上一篇: iOS-自定义cell
推荐阅读
-
Spring系列教程——11编程实现AOP
-
11、ABPZero系列教程之拼多多卖家工具 拼团提醒功能页面实现
-
Spring实现银行业务介绍(loc控制反转、AOP编程、事务、标签)
-
Spring面向切面编程(AOP)原理一之使用JDK实现动态代理
-
Spring之注解实现aop(面向切面编程)
-
Spring之注解实现aop(面向切面编程)
-
Spring系列教程——11编程实现AOP
-
Spring MVC实战系列教程(4)--0配置实现spring mvc应用
-
Spring实现银行业务介绍(loc控制反转、AOP编程、事务、标签)
-
11、ABPZero系列教程之拼多多卖家工具 拼团提醒功能页面实现