目录html
接口:IUserDao.java public interface IUserDao { void save(); } 目标对象类:UserDao.java public class UserDao implements IUserDao { public void save() { System.out.println("----已经保存数据!----"); } } 代理对象:UserDaoProxy.java public class UserDaoProxy implements IUserDao{ //接收保存目标对象 private IUserDao target; public UserDaoProxy(IUserDao target){ this.target=target; } public void save() { System.out.println("开始事务..."); target.save();//执行目标对象的方法 System.out.println("提交事务..."); } } 测试类:App.java public class App { public static void main(String[] args) { //目标对象 UserDao target = new UserDao(); //代理对象,把目标对象传给代理对象,创建代理关系 UserDaoProxy proxy = new UserDaoProxy(target); proxy.save();//执行的是代理的方法 } }
代理类所在包:java.lang.reflect.Proxy
JDK实现代理只须要使用newProxyInstance方法,可是该方法须要接收三个参数,完整的写法是:java
static Object newProxyInstance(ClassLoader loader, Class [] interfaces, InvocationHandler handler) 注意该方法是在Proxy类中是静态方法,且接收的三个参数依次为:
java.lang.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,一般在该方法中实现对委托类的代理访问。编程
// 该方法负责集中处理动态代理类上的全部方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象 // 第三个方法是调用参数。 Object invoke(Object proxy, Method method, Object[] args)
接口类IUserDao.java以及接口实现类UserDao是同样的.在这个基础上,增长一个代理工厂类(ProxyFactory.java),将代理类写在这个地方,而后在测试类中先创建目标对象和代理对象的联系,而后使用代理对象中的同名方法segmentfault
代理工厂类:ProxyFactory.java /** * 建立动态代理对象 * 动态代理不须要实现接口,可是须要指定接口类型 */ public class ProxyFactory{ //维护一个目标对象 private Object target; public ProxyFactory(Object target){ this.target=target; } //给目标对象生成代理对象 public Object getProxyInstance(){ return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开始事务2"); //执行目标对象方法 Object returnValue = method.invoke(target, args); System.out.println("提交事务2"); return returnValue; } } ); } } 测试类:App.java /** * 测试类 */ public class App { public static void main(String[] args) { // 目标对象 IUserDao target = new UserDao(); // 【原始的类型 class cn.itcast.b_dynamic.UserDao】 System.out.println(target.getClass()); // 给目标对象,建立代理对象 IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance(); // class $Proxy0 内存中动态生成的代理对象 System.out.println(proxy.getClass()); // 执行方法 【代理对象】 proxy.save(); } }
@Override public Object invoke(Object instance, Method method, Object[] args) throws Throwable { String clazz = manager.getClass().getName(); String methodName = method.getName(); if (args==null) { try { return method.invoke(manager, args); } catch (InvocationTargetException e) { throw e.getCause();// 关键在于要抛出真实的异常,若是多层次代理调用,则须要循环处理 } } ... }
public class PrivilegeValidationProxy<T extends MetaBean> implements InvocationHandler { protected MetaManager<T> manager; public PrivilegeValidationProxy(MetaManager<T> manager) { super(); this.manager = manager; } @Override public Object invoke(Object instance, Method method, Object[] args) throws Throwable { ... // 验证权限 valid(); method.invoke(manager, args); } } public class DatasetManager extends MetaManager<DatasetBean> implements DatasetManagerI { public static DatasetManagerI instance = newInstance(); public static DatasetManagerI getInstance() { return instance; } public static DatasetManagerI newInstance() { DatasetManager manager = new DatasetManager(); return (DatasetManagerI) Proxy.newProxyInstance(manager.getClass().getClassLoader(), new Class[] { DatasetManagerI.class }, new PrivilegeValidationProxy<DatasetBean>(manager)); } }
目标对象类:UserDao.java /** * 目标对象,没有实现任何接口 */ public class UserDao { public void save() { System.out.println("----已经保存数据!----"); } } Cglib代理工厂:ProxyFactory.java /** * Cglib子类代理工厂 * 对UserDao在内存中动态构建一个子类对象 */ public class ProxyFactory implements MethodInterceptor{ //维护目标对象 private Object target; public ProxyFactory(Object target) { this.target = target; } //给目标对象建立一个代理对象 public Object getProxyInstance(){ //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.建立子类(代理对象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("开始事务..."); //执行目标对象的方法 Object returnValue = method.invoke(target, args); System.out.println("提交事务..."); return returnValue; } } 测试类: /** * 测试类 */ public class App { @Test public void test(){ //目标对象 UserDao target = new UserDao(); //代理对象 UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance(); //执行代理对象的方法 proxy.save(); } }
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,经过对这些行为的分离,咱们但愿能够将它们独立到非业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码---解耦。
**在Spring的AOP编程中:设计模式