一:创建一个能对所有类实例进行动态代理的代理工具类
/*
* 创建一个能对所有类实例进行动态代理的代理工具类, 这里的泛型类型T 必须是接口类型
*/
public class DynamicProxy2<T> implements InvocationHandler {
private T target; // 被代理对象
/*
* 构造方法 传递一个被代理对象
*/
public DynamicProxy2(T target) {
this.target = target;
}
/*
* 获得代理对象
*/
public T getProxy() {
Object o = Proxy.newProxyInstance(DynamicProxy2.class.getClassLoader(),
target.getClass().getInterfaces(),
this);
return (T) o;
}
/*
* 复写invoke方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (!method.isAnnotationPresent(Transaction.class)) { // 如果接口方法中不存在事务注解, 则不开启事务
return method.invoke(target, args);
} else { // 如果接口方法中存在事务注解, 则开启事务
Connection connection = null;
Object obj = null;
try {
connection = DataSourceUtils.getConnection();
connection.setAutoCommit(false);
obj = method.invoke(target, args);
connection.commit();
} catch (Exception e) {
connection.rollback();
throw new Exception(e);
} finally {
connection.close();
}
return obj;
}
}
}
二:创建控制事务是否开启的注解
/*
* 控制事务是否开启的注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transaction {
}
三:使用
public interface IUserService {
@Transaction // 开始事务
void save() throws Exception;
Role getRole() throws Exception;
}
public class UserServiceImpl implements IUserService {
UserDao1 userDao1 = new UserDao1();
UserDao2 userDao2 = new UserDao2();
@Override
public void save() throws Exception {
userDao1.save();
userDao2.save();
}
@Override
public Role getRole() throws Exception {
return userDao2.getRole();
}
public static void main(String[] args) {
IUserService userService = new UserServiceImpl();
IUserService userService2 = new DynamicProxy2<IUserService>(userService).getProxy();
// try {
// userService2.save(); // 这个是否开启事务
// System.out.println("保存成功!");
// } catch (Exception e) {
// System.out.println("保存失败!");
// }
try {
userService2.getRole(); // 这个方法不需要开启事务
System.out.println("获得成功!");
} catch (Exception e) {
System.out.println("获得失败!");
}
}
}