代理 、动态代理 代理概念: 中介,即为单或多个服务类对象提供一种服务以控制其他类对该对象的访问。
在某些情况下,一个对象不适合或不能直接引用另一个对象,代理对象可以在请求类和目标类之间起到中介的作用。 代理模式: 代理模式是一种设计模式
jdk: reflect
代理的作用: 1。功能增强 在执行目标类的功能的同时可以进行 2。访问控制 控制访问类是否能访问目标类。
代理: 接口: SellingFigure.interface 接口实现类:厂商 .java implement SellingFigure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 package StaticProxy;public class bilibiliProxy implements SellFigure { private SellFigure s; public bilibiliProxy (SellFigure s) { this .s = s; } public int SellingFigure (String buyerName) { int oprice=s.SellingFigure(buyerName); double sprice= oprice+(oprice*0.25 ); System.out.println("您通过bilibili购买:" ); return (int ) sprice; } } package StaticProxy;public interface SellFigure { public int SellingFigure (String proxyname) ; } package StaticProxy;public class SellingImpl implements SellFigure { public SellingImpl () { } public int SellingFigure (String proxyname) { System.out.println("此为目标实现类的目标方法。 static way" ); int price; if (proxyname.equals("bilibili" )) price=980 ; else if (proxyname.equals("acfun" )) price=680 ; else price=900 ; return price; } } Typo=bilibili methodName=SellingFigure implName=SellingImpl name=SellFigure package StaticProxy;import org.junit.Test;import java.io.InputStream;import java.lang.reflect.Method;import java.util.Properties;public class otakuTest {@Test public void test1 () { SellFigure s = new SellingImpl(); System.out.println("死宅1号买入价格:" + s.SellingFigure("myself" ) ); } @Test public void test2 () throws Exception { ClassLoader clz=otakuTest.class .getClassLoader () ; InputStream clzs = clz.getSystemResourceAsStream("staticReflect.properties" ); Properties pro = new Properties(); pro.load(clzs); String typo = pro.getProperty("Typo" ); String methodname = pro.getProperty("methodName" ); String classname ="staticProxy." +typo+"Proxy" ; String implename = "staticProxy." +pro.getProperty("implName" ); Class clazz = Class.forName(classname); Class implclazz = Class.forName(implename); Object obj = clazz.getConstructor(SellFigure.class ).newInstance (implclazz .newInstance ()) ; Method met = clazz.getDeclaredMethod(methodname,String.class ) ; met.setAccessible(true ); Object a = met.invoke(obj,typo); System.out.println(a); } @Test public void test3 () { SellFigure s = new acfunProxy(new SellingImpl()); System.out.println("死宅3号买入价格:" + s.SellingFigure("acfun" ) ); } } 1 .jdkpackage Dynamicproxy.jdks;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class DbilibiliProxy implements InvocationHandler { public DbilibiliProxy (Object target) { this .target = target; } private Object target; public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { System.out.println("通过辅助代理bilibili" ); Object res = method.invoke(target,args); if (res!=null ){ Integer price=(Integer) res; price=(int )(price*1.25 ); res=price; } return res; } } package Dynamicproxy.jdks;import java.io.InputStream;import java.util.Properties;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class otaku { public static void main (String[] args) throws Exception { ClassLoader clz = otaku.class .getClassLoader () ; InputStream clzs = clz.getSystemResourceAsStream("staticReflect.properties" ); Properties pro = new Properties(); pro.load(clzs); String typo = pro.getProperty("Typo" ); String interfaceName = pro.getProperty("name" ); String proxyName = "dynamicproxy.jdks." + "D" + typo + "Proxy" ; interfaceName = "dynamicproxy.jdks." + interfaceName; String implename = "dynamicproxy.jdks." + pro.getProperty("implName" ); InvocationHandler proxyhandler = (InvocationHandler) Class.forName(proxyName).getConstructor(Object.class ).newInstance (Class .forName (implename ).newInstance ()) ; SellFigure dynamicWay = (SellFigure) Proxy.newProxyInstance(Class.forName(interfaceName).getClassLoader(), Class.forName(implename).getInterfaces(), proxyhandler); System.out.println(dynamicWay.SellingFigure(typo)); } } 2 .cglib代理package Dynamicproxy.cglib;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class DynamicCglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); private Object target; public DynamicCglibProxy (Object obj) { target = obj; } public Object getProxy () { enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this ); return enhancer.create(); } @Override public Object intercept (Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("通过动态代理实现" ); Object result = method.invoke(target, objects); System.out.println("由cglib代理出售了!" ); int t = (int ) ((Integer)result *1.25 ); result=t; return result; } } package Dynamicproxy.cglib;public class Selling { int price; public int SellingFigure (String proxyname) { System.out.println("此为目标实现类的目标方法。dynamic way " ); if (proxyname.equals("bilibili" )) price=980 ; else if (proxyname.equals("acfun" )) price=680 ; else price=900 ; return price; } } package Dynamicproxy.cglib;public class otaku { public static void main (String[] args) { Selling Sellfigure = new Selling(); DynamicCglibProxy dynamicCglibProxy = new DynamicCglibProxy(Sellfigure); Selling sellProxy = (Selling) dynamicCglibProxy.getProxy(); System.out.println(sellProxy.SellingFigure("bilibili" ));; } }
动态代理分两类 jdk自带的动态代理reflect Proxy 和cglib第三方类,分别的实现原理是反射、ASM(字节码编译)。 反射速率会差上一大截。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Create JDK Proxy: 13 ms Create CGLIB Proxy: 217 ms Create JAVAASSIST Proxy: 99 ms Create JAVAASSIST Bytecode Proxy: 168 ms Create ASM Proxy: 3 ms ================ Run JDK Proxy: 2224 ms, 634 ,022 t/s Run CGLIB Proxy: 1123 ms, 1 ,255 ,623 t/s Run JAVAASSIST Proxy: 3212 ms, 438 ,999 t/s Run JAVAASSIST Bytecode Proxy: 206 ms, 6 ,844 ,977 t/s Run ASM Bytecode Proxy: 209 ms, 6 ,746 ,724 t/s