import java.util.ArrayList; import java.util.List; /** * 装饰器模式: 侧重于对目标类中核心逻辑的扩展, 依然是以目标类为中心 * 代理模式 : 侧重于对目标类的访问限制于处理,或者对其添加一些重用性且与 核心业务逻辑无关的功能, 例如日志. */ public class ProxyModel { } interface IDao{ void add(Object o); void delete(Object o); void update(int id,Object o); Object find(int id); } class SimpleDao implements IDao{ private List<Object> mDataBase = new ArrayList<>(); @Override public void add(Object o) { mDataBase.add(o); } @Override public void delete(Object o) { mDataBase.remove(o); } @Override public void update(int id,Object o) { mDataBase.remove(id); mDataBase.add(id,o); } @Override public Object find(int id) { return mDataBase.get(id); } } class DaoProxy implements IDao{ private IDao iDao; public DaoProxy() { } public DaoProxy(IDao iDao) { this.iDao = iDao; } private void beginTransaction(){ System.out.println("开始操做数据库"); } private void commit(){ System.out.println("结束操做数据库"); } @Override public void add(Object o) { this.beginTransaction(); iDao.add(o); this.commit(); } @Override public void delete(Object o) { this.beginTransaction(); iDao.delete(o); this.commit(); } @Override public void update(int id, Object o) { this.beginTransaction(); iDao.update(id,o); this.commit(); } @Override public Object find(int id) { this.beginTransaction(); Object o = iDao.find(id); this.commit(); return o; } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; /** * 动态代理: 相对于静态代理, 动态代理中的代理类不须要事先与目标类相同的接口, 并且不依赖于接口的具体实现, 理论上能够代理全部类的全部方法. 但由于要考虑到涉及到的业务, 因此要求面向接口代理. * 实现机制: 运行时建立一个虚拟的代理类, 在代理的目标方式实际执行时, 经过java的反射技术获取到该防范对象, 并在执行先后后添加须要的操做, 这须要实现一个`InvocationHandler接口 */ public class ProxyModel { public static void main(String[] args) { SimpleDao simpleDao = new SimpleDao(); IDao proxy = new DaoProxy().createProxy(simpleDao); proxy.add("ss"); } } interface IDao { void add(Object o); void delete(Object o); void update(int id, Object o); Object find(int id); } class SimpleDao implements IDao{ private List<Object> mDataBase = new ArrayList<>(); @Override public void add(Object o) { mDataBase.add(o); } @Override public void delete(Object o) { mDataBase.remove(o); } @Override public void update(int id,Object o) { mDataBase.remove(id); mDataBase.add(id,o); } @Override public Object find(int id) { return mDataBase.get(id); } } class DaoProxy { /*这里须要注意, 返回值只能是一个接口, 而不能使具体的实现类. */ public IDao createProxy(IDao target) { /*此方法生成的虚拟类是根据目标的Class文件拿到的父类接口生成的, 所以不能强制转换成实现类 */ return (IDao) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { beginTransaction(); Object invoke = method.invoke(target, args); commit(); return invoke; } }); } private void beginTransaction() { System.out.println("读写开始前,开启数据库!"); } private void commit() { System.out.println("读写结束,关闭数据库!"); } }
/** * 不关心接口的实现逻辑, 只须要取到备操做类便可. */ public class ProxyModel { public static void main(String[] args) { IDao proxy = new LogProxy().createProxy(SimpleDao.class); proxy.add("item"); proxy.delete("asd"); proxy.update(1,"asd"); } } interface IDao { void add(Object o); void delete(Object o); void update(int id, Object o); Object find(int id); } class SimpleDao implements IDao{ @Override public void add(Object o) { System.out.print("添加: "+o.toString()+" "); } @Override public void delete(Object o) { System.out.print("删除: "+o.toString()+" "); } @Override public void update(int id,Object o) { System.out.print("更新: "+id+" "+o.toString()+" "); } @Override public Object find(int id) { System.out.print("查找: "+id+" "); return null; } } class LogProxy { public <T> T createProxy(Class<T> target) { return (T) Proxy.newProxyInstance(target.getClassLoader(), target.getInterfaces(), (proxy, method, args) -> { System.out.print("开始输出日志------->"); System.out.print("调用方法:" + method.getName() + makeArgsText(args)); method.invoke(target.newInstance(),args); System.out.print("<-------日志输出结束"); System.out.println(); return null; }); } private String makeArgsText(Object[] args) { StringBuilder builder = new StringBuilder(); builder.append(", 共有").append(args.length).append("个参数: "); for(Object item : args) { builder.append(item.toString()).append(" & "); } return builder.toString(); } }
import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * 若是目标类没有实现接口, 那么`Spring AOP`会选择使用`CGLIB`来动态代理目标类. * CGLIB(Code Generation Library), 是一个代码生成的类库, 能够在运行时动态的生成某个类的子类. * CGLIB是经过继承的方式作的动态代理, 所以若是某个类被标记为Final,那么它是没法使用CGLIB作动态代理的. */ class SimpleDao { public void add(Object o) { System.out.println("添加: " + o.toString() + " "); } public void delete(Object o) { System.out.println("删除: " + o.toString() + " "); } public void update(int id, Object o) { System.out.println("更新: " + id + " " + o.toString() + " "); } public Object find(int id) { System.out.println("查找: " + id + " "); return null; } } class MyMethodInterceptor implements MethodInterceptor { /** * sub:cglib生成的代理对象 * method:被代理对象方法 * objects:方法入参 * methodProxy: 代理方法 */ @Override public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("======插入前置通知======"); Object object = methodProxy.invokeSuper(sub, objects); System.out.println("======插入后者通知======"); return object; } } class Client { public static void main(String[] args) { // 经过CGLIB动态代理获取代理对象的过程 Enhancer enhancer = new Enhancer(); // 设置enhancer对象的父类 enhancer.setSuperclass(SimpleDao.class); // 设置enhancer的回调对象 enhancer.setCallback(new MyMethodInterceptor()); // 建立代理对象 SimpleDao proxy = (SimpleDao) enhancer.create(); // 经过代理对象调用目标方法 proxy.add("add"); } }