按照平时写代码的习惯,我们会定义一个service接口
package com.proxy.test;
public interface UserService {
public void sayHello(String word);
}
接着是实现类
package com.proxy.test;
public class UserServiceImpl implements UserService{
@Override
public void sayHello(String word) {
System.out.println("执行dao的删除操作,添加一个用户:" + word);
System.out.println("执行dao的删除添加,删除一个用户:" + word);
}
}
我们的目的是,执行sayHello中的添加删除操作时,让这几条sql语句同时提交(commit)或同时回滚(rollback),下面我们用动态代理的方式,实现这个功能:
自定义一个代理管家,帮我们创建代理类,需要实现InvocationHandler接口(必须)
package com.proxy.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyProxyManager implements InvocationHandler {
private Object target;
public Object bind(Object target){
this.target = target;
/*
* Proxy.newProxyInstance 会返回一个代理对象
* target.getClass() --> 被代理对象的ClassLoader,这里实际对应UserServiceImpl类
* target.getClass().getInterfaces() --> 被代理对象实现的接口列表(UserService),指定之后,代理对象就可以使用其接口中的方法了
* this -- 表示的是当这个动态代理对象在调用方法的时候,会通过哪个InvocationHandler,这里实际是MyProxyManager这个类
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 我们通过MyProxyManager创建出来的代理对象在调用自己的方法时,
* 会通过invoke这个方法进行调用,而不是直接调用
* @param proxy 被代理对象
* @param method 被代理对象执行的方法
* @param args 被代理对象执行的方法所需要的参数
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
System.out.println("我是动态代理对象");
System.out.println("准备进入事务..");
Object result = null;
try{
// 执行被代理对象自己的方法
result = method.invoke(target, args);
}catch(Exception e){
// 如果有错误,执行数据库的rollBack方法
System.out.println("执行rollBack");
}
// 如果没错,执行数据库的commit方法
System.out.println("执行commit");
System.out.println("-----------------------");
return result;
}
}
测试代码
public static void main(String[] args) {
MyProxyManager manager = new MyProxyManager();
// 创建UserService的代理对象
UserService userService = (UserService) manager.bind(new UserServiceImpl());
userService.sayHello("lalala");
}
运行看一下效果:
我是动态代理对象
准备进入事务..
执行dao的删除操作,添加一个用户:lalala
执行dao的删除添加,删除一个用户:lalala
执行commit
这里只是使用打印语句简单模拟了数据库的操作,没有真正连接数据库操作,有空的童鞋可以实际操作一下。
我们平时用到的spring的事务管理、springmvc的interceptor都是aop的实例
spring把事务操作放到了代理类中统一commit或rollback
interceptor本身就是一个代理类,在调用指定方法前后添加一系列操作