本文共 11684 字,大约阅读时间需要 38 分钟。
拿到代理目标对象的引用
实现功能增强 保护目标对象public interface ISubject { void request();}
public class RealSubject implements ISubject{ @Override public void request() { System.out.println("real service is called"); }}
public class Proxy implements ISubject{ private ISubject subject; @Override public void request() { before(); subject.request(); after(); } public Proxy(ISubject subject){ this.subject = subject; } public void before(){ System.out.println("called before request()."); } public void after(){ System.out.println("called after request()."); }}
public class Client { public static void main(String[] args) { Proxy proxy = new Proxy(new RealSubject()); proxy.request(); }}
public interface IPerson { void findLove();}
public class LisiSon implements IPerson { @Override public void findLove() { System.out.println("要求: 肤白貌美大长腿"); }}
public class Wangwu implements IPerson { @Override public void findLove() { System.out.println("合适就好"); }}
public class Lisi implements IPerson { private LisiSon lisiSon; public Lisi(LisiSon lisiSon){ this.lisiSon = lisiSon; } @Override public void findLove() { System.out.println("开始物色"); lisiSon.findLove(); System.out.println("开始交往"); }}
public class Test { public static void main(String[] args) { Lisi lisi = new Lisi(new LisiSon()); //Lisi lisi1 = new Lisi(new Wangwu()); 代理不了 lisi.findLove(); }}
public interface IPerson { void findLove(); void buySafe();}
public class LisiSon implements IPerson { @Override public void findLove() { System.out.println("要求: 肤白貌美大长腿"); } @Override public void buySafe() { System.out.println("购买30万保险"); }}
public class Wangwu implements IPerson { @Override public void findLove() { System.out.println("要求: 有车有房学历高"); } @Override public void buySafe() { System.out.println("购买100万保险"); }}
public class JdkMatchmaker implements InvocationHandler { private IPerson target; public IPerson getInstance(IPerson target){ this.target = target; Class clazz = target.getClass(); return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object invoke = method.invoke(this.target, args); after(); return invoke; } private void after() { System.out.println("开始物色"); } private void before() { System.out.println("开始交往"); }}
public class Test { public static void main(String[] args) { JdkMatchmaker jdkMatchmaker = new JdkMatchmaker(); IPerson instance = jdkMatchmaker.getInstance(new LisiSon()); instance.findLove(); instance.buySafe(); // IPerson instance1 = jdkMatchmaker.getInstance(new Wangwu()); instance1.findLove(); instance1.buySafe(); //为了看一眼JDK动态生成的代理类 byte[] $Proxy0s = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{ IPerson.class}); try { FileOutputStream os = new FileOutputStream("/opt/workspace/2020/09/22/$Proxy0.class"); os.write($Proxy0s); os.close(); } catch (IOException e) { e.printStackTrace(); } }}
public class LisiSon { public void findLove() { System.out.println("要求: 肤白貌美大长腿"); } public void buySafe() { System.out.println("购买30万保险"); }}
public class CglibMatchmaker implements MethodInterceptor { public Object getInstance(Class clazz){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } private void after() { System.out.println("开始交往"); } private void before() { System.out.println("开始物色"); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { before(); Object invoke = methodProxy.invokeSuper(o, objects); after(); return invoke; }}
public class Test { public static void main(String[] args) { //CGlib 采用继承的方式,覆盖父类的方法 //JDK 采用的实现方式,必须要求代理的目标对象一定要实现一个接口 //思想:都是通过生成字节码,重组成一个新的类 //JDK Proxy 对于用户而言,依赖更强,调用也更复杂 //Cglib 对目标类没有任何的要求 //CGlib 效率更高,性能也更高,低层没有用到反射 //JDK Proxy 生成逻辑较为简单,执行效率要低,每次都要用反射 //Cglib 有个坑,目标代理类不能有final修饰的方法,忽略final修饰的方法 //生成cglib的动态代理类,用于查看动态生成的代码 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"/opt/workspace/2020/09/22/.cglib_proxy_class"); LisiSon lisi = (LisiSon)new CglibMatchmaker().getInstance(LisiSon.class); lisi.findLove(); lisi.buySafe(); }}
public interface MyInvocationHandler { Object invoke(Object proxy, Method method, Object[] args) throws Throwable;}
public class MyClassLoader extends ClassLoader{ private File classPathFile; public MyClassLoader(){ String classPath = MyClassLoader.class.getResource("").getPath(); this.classPathFile = new File(classPath); } @Override protected Class findClass(String name) throws ClassNotFoundException { String className = MyClassLoader.class.getPackage().getName() + "." + name; if(classPathFile != null){ File classFile = new File(classPathFile,name.replaceAll("\\.","/") + ".class"); FileInputStream in = null; ByteArrayOutputStream out = null; try { in = new FileInputStream(classFile); out = new ByteArrayOutputStream(); byte[] buff = new byte[1024]; int len; while ((len = in.read(buff)) != -1) { out.write(buff, 0, len); } return defineClass(className, out.toByteArray(), 0, out.size()); }catch (Exception e){ e.printStackTrace(); } } return super.findClass(name); }}
public class MyProxy { public static final String LN = "\r\n"; public static Object newProxyInstance(MyClassLoader loader, Class [] interfaces, MyInvocationHandler h) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //1.动态生成源代码 String src = generateSrc(interfaces); //2.java文件输出到磁盘,保存为文件$Proxy0.java String filePath = MyProxy.class.getResource("").getPath(); File f = new File(filePath + "$Proxy0.java"); FileWriter fw = new FileWriter(f); fw.write(src); fw.flush(); fw.close(); //3.把.java文件编译成$Proxy0.class文件 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null); Iterable javaFileObjects = standardFileManager.getJavaFileObjects(f); JavaCompiler.CompilationTask task = compiler.getTask(null, standardFileManager, null, null, null, javaFileObjects); task.call(); //4.把生成的.class文件加载到jvm中 Class proxyClass = loader.findClass("$Proxy0"); Constructor constructor = proxyClass.getConstructor(MyInvocationHandler.class); //5.返回新的代理对象 f.delete(); return constructor.newInstance(h); } private static String generateSrc(Class [] interfaces) { StringBuilder sb = new StringBuilder(); sb.append("package com.study.pattern.proxy.dynamicproxy.myproxy.proxy;" + LN); sb.append("import com.study.pattern.proxy.dynamicproxy.myproxy.client.IPerson;" + LN); sb.append("import java.lang.reflect.*;" + LN); sb.append("public final class $Proxy0 implements " + interfaces[0].getName() + "{" + LN); sb.append("MyInvocationHandler h;" + LN); sb.append("public $Proxy0(MyInvocationHandler h){ " + LN); sb.append("this.h = h;" + LN); sb.append("}" + LN); for(Method m : interfaces[0].getMethods()){ Class [] params = m.getParameterTypes(); StringBuilder paramNames = new StringBuilder(); StringBuilder paramValues = new StringBuilder(); StringBuilder paramClasses = new StringBuilder(); for(int i = 0; i < params.length; i++){ } sb.append("public " + m.getReturnType().getName() + " " + m.getName() + "(){" + LN); sb.append("try{ " + LN); sb.append("Method m =" + interfaces[0].getName() + ".class.getMethod(\""+ m.getName() + "\",new Class[]{});" + LN); sb.append("this.h.invoke(this,m,new Object[]{});" + LN); sb.append("return;" +LN); sb.append("}catch (RuntimeException | Error var3) {" +LN); sb.append(" throw var3;" +LN); sb.append(" } catch (Throwable var4) {" +LN); sb.append(" throw new UndeclaredThrowableException(var4);" +LN); sb.append(" }"); sb.append("}" + LN); } sb.append("}"); return sb.toString(); }}
public interface IPerson { void findLove(); void buySafe();}
public class LisiSon implements IPerson { @Override public void findLove() { System.out.println("要求: 肤白貌美大长腿"); } @Override public void buySafe() { System.out.println("购买30万保险"); }}
public class MyMatchmaker implements MyInvocationHandler { private IPerson target; public IPerson getInstance(IPerson target) throws NoSuchMethodException, IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException { this.target = target; Class clazz = target.getClass(); return (IPerson) MyProxy.newProxyInstance(new MyClassLoader(),clazz.getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object invoke = method.invoke(this.target, args); after(); return invoke; } private void after() { System.out.println("开始物色"); } private void before() { System.out.println("开始交往"); }}
public class Test { public static void main(String[] args) throws NoSuchMethodException, IOException, ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException { MyMatchmaker myMatchmaker = new MyMatchmaker(); IPerson instance = myMatchmaker.getInstance(new LisiSon()); instance.findLove(); instance.buySafe(); }}
转载地址:http://ckjrn.baihongyu.com/