基于代理类实现Spring AOP
2020-12-13 05:22
标签:ssi nbsp 代码 回调 部分 事务管理 实例化 参数 载器 ProxyFactoryBean类介绍 基于JDK动态代理的Spring AOP实现 基于CGLIB代理的Spring AOP实现 Spring的通知类型 虽然直接使用代理就可以创建代理的实例,但需要自己写创建代理的方法,比如JDK动态代理: CGLIB代理: 什么乱七八糟的过程、方法,我哪记得住。ProxyFactoryBean类可解决此问题。 ProxyFactoryBean是FactoryBean接口的一个实现类,FactoryBean接口的作用是实例化一个Bean,ProxyFactoryBean类的作用实例化一个Bean的代理,我们在xml文件中配置代理即可,不必手写创建代理的方法。 1、新建包user,用于写被代理的类、接口。包下新建接口UserInterface 再新建一个实现类User 2、新建包aspect,用来写切面类。包下新建类MyAspect,需实现MethodInterceptor接口,此接口是org.aopalliance.intercept包下的接口,不要import导入错了。(需要aopalliance.jar包的支持) 当然,可以实现其它的接口(Spring的通知类型)。不同的接口,提供的功能不同。 3、在xml中配置代理 ProxyFactoryBean类已经写好了创建代理代码,这个类使用setter方法注入依赖,我们只需要用 4、新建包test,包下新建测试类Test 运行,控制台输出如下 代理成功。 JDK动态代理代理的是接口,CGLIB代理的类,所以我们只需要把上例中有关接口的部分去掉即可。也可一步步从头开始。 1、新建包user,包下新建类User 2、新建包aspect,包下新建切面类MyAspect 3、在xml中配置代理 去掉指定接口的那句配置就ok。 4、新建包test,包下新建测试类Test 运行,控制台输出如下 代理成功。 需要2个包:spring-aop.jar,这个是Spring自带的,不用管。aopalliance.jar,如果使用了maven或IDEA的自动下载Spring所需的包,会自动添加这个包,不用管,如果是手动添加Spring需要的包,则还需要自己去下载、添加这个包。 在例子的切面类中,我们实现的是MethodInterceptor接口,这个接口是环绕通知的接口,可在目标方法前后实施增强,可用于日志、事务管理等。 Spring的5种通知类型 可根据需要,选择实现接口。 Advice指的就是目标方法。增强其实就是做一些额外的处理。 基于代理类实现Spring AOP 标签:ssi nbsp 代码 回调 部分 事务管理 实例化 参数 载器 原文地址:https://www.cnblogs.com/chy18883701161/p/11139169.html目录
ProxyFactoryBean类
1 ........
2 //创建代理方法,参数是目标接口的实例
3 public Object createProxy(UserInterface user){
4 this.user=user; //初始化目标接口实例
5
6 ClassLoader classLoader=JdkProxy.class.getClassLoader(); //获取当前类的类加载器,当前类类名.class.getClassLoader()
7 Class[] classArr=user.getClass().getInterfaces(); //获取目标接口实例实现的全部接口
8
9 //参数:当前类的类加载器,目标接口实例实现的所有接口,当前类的实例
10 return Proxy.newProxyInstance(classLoader,classArr,this);
11 }
1 //创建代理,参数是Object类型
2 public Object createProxy(Object target){
3 Enhancer enhancer=new Enhancer(); //创建一个动态类对象
4 enhancer.setSuperclass(target.getClass()); //将这个动态类对象的父类/基类设置为目标类(需要增强的类)
5 enhancer.setCallback(this); //设置回调
6 return enhancer.create(); //返回创建的代理
7 }
基于JDK动态代理的Spring AOP实现
1 public interface UserInterface {
2 public void addUser();
3 public void alterUser();
4 public void deleteUser();
5 }
1 public class User implements UserInterface {
2 @Override
3 public void addUser() {
4 //模拟添加用户
5 System.out.println("正在添加用户");
6 System.out.println("添加用户成功");
7 }
8
9 @Override
10 public void alterUser() {
11 //模拟修改用户信息
12 System.out.println("正在修改用户信息");
13 System.out.println("修改用户信息成功");
14 }
15
16 @Override
17 public void deleteUser() {
18 //模拟删除用户
19 System.out.println("正在删除用户");
20 System.out.println("删除用户成功");
21 }
22 }
1 public class UserProxy implements MethodInterceptor {
2 @Override
3 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
4 checkPermission(); //前增强
5 Object object=methodInvocation.proceed(); //通过invoke()的参数调用
6 log(); //后增强
7 return object;
8 }
9
10 public void checkPermission(){
11 //模拟检查权限
12 System.out.println("正在检查权限");
13 System.out.println("权限已够");
14 }
15
16 public void log(){
17 //模拟记录日志
18 System.out.println("正在记录日志");
19 System.out.println("日志已记录");
20 }
21 }
1 public class Test {
2 public static void main(String[] args) {
3 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
4 //因为使用的JDK动态代理,代理的是接口,所以要使用接口来声明
5 UserInterface user=applicationContext.getBean("userProxy", UserInterface.class);
6 user.addUser();
7 }
8 }
正在检查权限
权限已够
正在添加用户
添加用户成功
正在记录日志
日志已记录
基于CGLIB代理的Spring AOP实现
1 public class User{
2 public void addUser() {
3 //模拟添加用户
4 System.out.println("正在添加用户");
5 System.out.println("添加用户成功");
6 }
7
8 public void alterUser() {
9 //模拟修改用户信息
10 System.out.println("正在修改用户信息");
11 System.out.println("修改用户信息成功");
12 }
13
14 public void deleteUser() {
15 //模拟删除用户
16 System.out.println("正在删除用户");
17 System.out.println("删除用户成功");
18 }
19 }
1 public class MyAspect implements MethodInterceptor {
2 @Override
3 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
4 checkPermission(); //前增强
5 Object object=methodInvocation.proceed(); //通过invoke()的参数调用
6 log(); //后增强
7 return object;
8 }
9
10 public void checkPermission(){
11 //模拟检查权限
12 System.out.println("正在检查权限");
13 System.out.println("权限已够");
14 }
15
16 public void log(){
17 //模拟记录日志
18 System.out.println("正在记录日志");
19 System.out.println("日志已记录");
20 }
21 }
1 public class Test {
2 public static void main(String[] args) {
3 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
4 //要使用目标类来声明
5 User user=applicationContext.getBean("userProxy", User.class);
6 user.addUser();
7 }
8 }
正在检查权限
权限已够
正在添加用户
添加用户成功
正在记录日志
日志已记录
说明
Spring的通知类型
通知类型
对应接口
增强时间
常见应用
环绕通知
MethodInterceptor
在目标方法执行前后实施增强
日志、事务处理
前置通知
MethodBeforeAdvice
在目标方法执行前进行增强
权限管理
后置通知
AfterReturningAdvice
在目标方法执行后进行增强
关闭流、上传文件、删除临时文件等
异常通知
ThrowsAdvice
在方法抛出异常后进行增强
处理异常、记录日志等
引介通知
IntroductionInterceptor
在目标类中添加一些新的属性、方法
修改旧版程序
下一篇:Python生成报表