需求描述:
抽取dao层开启和提交事物交由代理类一并执行
分析:
假如UserDao接口中有很多方法,例如addUser()、deleteUser()、updateUser()等等,需要频繁的和数据库打交道,必然在每个方法里都会有开启事物,提交事务的操作。如果把开启事物和提交事物写在一个类A中不同方法中,由一个工厂将dao层和A类进行整合,得到一个代理的UserDao的实现对象,它即有原UserDao实现类中的各个方法,又有A类中的事物方法。即可实现切面管理事物。
代码:
UserDao接口:
package com.xx.dao; public interface UserDao { //增 void addUser(); //删 void deleteUser(); //改 void updateUser(); }
UserDaoImpl实现类:
package com.xx.dao; public class UserDaoImpl implements UserDao{ @Override public void addUser() { System.out.println("添加用户"); } @Override public void deleteUser() { System.out.println("删除用户"); } @Override public void updateUser() { System.out.println("更新用户"); } }
切面类:
package com.xx.dao; public class MyAspect { public void before(){ System.out.println("开启事物"); } public void after(){ System.out.println("关闭事物"); } }
代理工厂类:
package com.xx.dao; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 代理工厂(代理UserDao生成特定功能的实现类对象) * @author phoebe * */ public class ProxyFactory { //被代理类 private static UserDao userDao = new UserDaoImpl(); //切面类 private static MyAspect myAspect = new MyAspect(); /* 获取新的代理类 * loader:类加载器(选当前类的类加载器) * 方法一:当前类.class.getClassLoader(); * 方法二:对象.getClass.getClassLoader(); * interfaces:代理生成的对象是哪个接口的实现类呢? * 方法一:new Class[]{接口.class} * 方法二:对象.getClass().getInterfaces(),此仅能返回当前对象实现类的接口,并不能返回其父接口 * InvocationHandler:使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy 实例。 */ public static UserDao createProxyUserService(){ UserDao proxyInstance = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object object = null; //可以通过method.getName()控制是否增强 if(!("updateUser".equals(method.getName()))){ myAspect.before(); object = method.invoke(userDao, args); myAspect.after(); System.out.println(object+"为什么是null?尚未知晓"); return object; } System.out.println(object+"为什么是null?尚未知晓"); return object; } }); //返回UserDao的新实例对象 return proxyInstance; } }
测试类:
package com.xx.action; import com.xx.dao.ProxyFactory; import com.xx.dao.UserDao; public class TestProxy { public static void main(String[] args) { UserDao userService = ProxyFactory.createUserService(); userService.addUser(); userService.deleteUser(); userService.updateUser(); } }
效果:
开启事物 -------添加用户------- 关闭事物 null为什么是null?尚未知晓 开启事物 -------删除用户------- 关闭事物 null为什么是null?尚未知晓 null为什么是null?尚未知晓