做电子请帖网站有哪些,浦北网站建设,软件外包公司是干什么的,广州十大家装品牌1 代理 1.1 代理的概念和作用 代理的概念很好理解#xff0c;就像黄牛代替票务公司给你提供票#xff0c;经纪人代理艺人和别人谈合作。Java的代理是指实现类作为代理类的属性对象#xff0c;代理类提供方法给外部调用#xff0c;代理类内部再去调用实现…1 代理 1.1 代理的概念和作用 代理的概念很好理解就像黄牛代替票务公司给你提供票经纪人代理艺人和别人谈合作。Java的代理是指实现类作为代理类的属性对象代理类提供方法给外部调用代理类内部再去调用实现类的方法实现具体的业务。也就是代理类作为对外接口人实现类不直接对外。这就是java代理的概念。 代理的作用是当你需要增加一些而外的操作而又不想去修改实现类的。可以通过代理来实现在代理类中增加附件的操作。例如需要增加权限过滤但是业务类已经开发好不想将权限和业务混在一起想让每个类的功能尽可能单一各司其职。此时我们就可以做一个该类的代理类由该代理类做权限判断如果安全则调用实际类的业务开始处理。 代理分为静态代理和动态代理动态代理有分为jdk动态代理和cglib动态代理。 1.2 静态代理 先定义一个接口Subject然后实现类RealSubject和代理类Proxy都继承这个接口实现接口的方法。代理类构造函数的形参是接口引用Subject subject实现类对象作为代理类构造函数的实参传入保存到代理类的接口类型的Subject属性中。用户调用代理类的方法代理类方法内部通过接口引用再去调用实现类的方法。 //定义接口 interface Subject { void request(); } //实现类实现接口 class RealSubject implements Subject { public void request(){ System.out.println(RealSubject); } } //代理类实现接口 class Proxy implements Subject { private Subject subject; public Proxy(Subject subject){//代理构造函数接口形参以实现类对象为实参 this.subject subject; } public void request(){ System.out.println(begin); subject.request();//调用实现类的方法 System.out.println(end); } } //调用实例 public class ProxyTest { public static void main(String args[]) { RealSubject subject new RealSubject();//创建实现类对象 Proxy p new Proxy(subject);//创建代理类对象 p.request();//调用代理类的方法内部再去调用实现类的request方法 } } 1.3 Jdk动态代理 1.3.1 Jdk动态代理实现 Jdk动态代理实际上是利用了java的反射机制。利用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口定义代理类的实现。将实现类的接口信息传入到代理类的静态构造函数Proxy.newProxyInstance中代理类的构造函数内部通过反射的机制获取实现类的方法代理类的代理方法对实现类的方法进行了包装。调用代理类的方法内部调用实现类的方法。实际上静态代理和动态代理本质上是一样的只是动态代理利用的反射的机制获取实现类的方法。 1//定义实现类继承的接口 public interface Service { //目标方法 public abstract void add(); } 2//实现类并继承接口实现方法add public class UserServiceImpl implements Service { public void add() { System.out.println(This is add service); } } 3利用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口定义代理类的实现。重写InvocationHandler的invoke方法。 class MyInvocatioHandler implements InvocationHandler { private Object target;//接口属性 public MyInvocatioHandler(Object target) {//构造函数实参实现类对象 this.target target; } //重写代理类InvocationHandler的invoke方法 Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(-----before-----); Object result method.invoke(target, args); System.out.println(-----end-----); return result; } // 生成代理对象方法 public Object getProxy() { //获取类加载器 ClassLoader loader Thread.currentThread().getContextClassLoader(); //获取实现类的方法接口提供反射机制的方法名称 Class?[] interfaces target.getClass().getInterfaces(); //调用Proxy的静态方法创建代理对象 return Proxy.newProxyInstance(loader, interfaces, this); } } 4使用动态代理实例 public class ProxyTest { public static void main(String[] args) { //创建实现类对象 Service service new UserServiceImpl(); //实现类对象以实参形式传入代理类保存在tartget属性中 MyInvocatioHandler handler new MyInvocatioHandler(service); //获取代理对象 Service serviceProxy (Service)handler.getProxy(); //通过代理对象调用方法 serviceProxy.add();//执行方法 } } 执行结果 -----before----- This is add service -----end----- 1.3.2 Jdk动态代理反推过程 从步骤4开始在逆向推到一遍。先创建一个实现类对象service作为入参传给 new MyInvocatioHandler(service);构造函数保存在target属性中。通过getProxy()方法创建代理对象。Proxy.newProxyInstance(loader, interfaces, this);入参分别是loader加载类对象interfaces实现类对象target的方法信息this是MyInvocatioHandler指针。在newProxyInstance函数内部通过反射机制根据interfaces传入的方法名称等信息获取实现类的方法method。同时代理类内部对实现类的每个方法都对应实现了代理方法。serviceProxy.add();调用了代理类的代理方法代理方法内部通过调用MyInvocatioHandler的invoke方法返回invoke(Object proxy, Method method, Object[] args)去调用实现类的Method。在invoke方法里面就可以增加其他的操作比如说日志打印其中Method参数是通过反射机制根据interfaces信息获取到的实现类的方法。和静态映射的原理差不多只是将代理类进行了包装。 1.3.3 jdk代理类源码解析 为了更清楚的理解动态代理通过以下方式把代理类字节码生成class文件。 byte[] classFile ProxyGenerator.generateProxyClass(com.sun.proxy.$Proxy.1, service.getClass().getInterfaces()); FileOutputStream out new FileOutputStream(com.sun.proxy.$Proxy.1.class); out.write(classFile); out.flush(); 使用 反编译工具 jad jad com.sun.proxy.$Proxy.1 看看代理类如何实现反编译出来的java代码如下 //代理类继承extends类和实现类一样也实现了Service接口 public final class $proxy1 extends Proxy implements Service { //构造函数 public $proxy1(InvocationHandler invocationhandler) { super(invocationhandler); } //代理类的代理方法 public final boolean equals(Object obj) { try { return ((Boolean)super.h.invoke(this, m1, new Object[] { obj })).booleanValue(); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String toString() { try { return (String)super.h.invoke(this, m2, null); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } //这里调用的是实现类add代理方法 public final void add() { try { //内部调用的是MyInvocatioHandler的invoke方法 super.h.invoke(this, m3, null); return; } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final int hashCode() { try { return ((Integer)super.h.invoke(this, m0, null)).intValue(); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } //定义静态Method变量 private static Method m1; private static Method m2; private static Method m3; private static Method m0; //通过反射机制和interfaces提供的信息获取实现类的方法 static { try { m1 Class.forName(java.lang.Object).getMethod(equals, new Class[] { Class.forName(java.lang.Object) }); m2 Class.forName(java.lang.Object).getMethod(toString, new Class[0]); //通过反射机制获取实现类的方法 m3 Class.forName(zzzzzz.Service).getMethod(add, new Class[0]); m0 Class.forName(java.lang.Object).getMethod(hashCode, new Class[0]); } catch(NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch(ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } } 1.4 不用实现接口的Cglib代理 1.4.1 Cglib代理的简单实现 静态代理和jdk动态代理都需要通过实现一个接口只能对该类接口中定义的方法实现代理这在实际编程中有一定的局限性。使用cglib[Code Generation Library]实现动态代理并不要求实现类必须实现接口。 使用步骤 1先定义实现类实现方法add public class UserServiceImpl { public void add() { System.out.println(This is add service); } } 2实现MyMethodInterceptor实现MethodInterceptor接口定义方法的拦截器intercept方法该对象会被传入代理类中相当于回调函数的作用代理类内部调用intercept方法intercept方法的四个参数1代理对象2实现类方法3方法参数4代理方法的MethodProxy对象。 public class MyMethodInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { System.out.println(Before: method); Object object proxy.invokeSuper(obj, arg); System.out.println(After: method); return object; } } 3利用Enhancer类生成代理类创建Enhancer enhancer对象将实现类作为入参传入enhancer作为代理类的父类。设置拦截器MyMethodInterceptor 到enhancer内部作为回调。 Enhancer enhancer new Enhancer();//创建Enhancer类对象 enhancer.setSuperclass(UserServiceImpl.class); //传入实现类的class为反射提供信息 同时实现类是Enhancer的父类 enhancer.setCallback(new MyMethodInterceptor()); //设置拦截器对象通过拦截器回调。Enhancer是CGLib的字节码增强器可以方便的对类进行扩展内部调用GeneratorStrategy.generate方法生成代理类。传入了实现类作为父类传入MyMethodInterceptor对象作为拦截回调。 UserServiceImpl userService (UserServiceImpl)enhancer.create();//创建代理类对象因为代理类继承了实现类所以可以用父类引用接收子类对象。 4userService.add()方法的执行输出结果。 Before: add This is add service After: add 1.4.2 代理类反向编译源码解析 对(UserServiceImpl)enhancer.create();返回的代理类进行反向编译得到代理类的源码如下。 这样可能还是不能理解代理类内部是怎么实现的 import net.sf.cglib.core.Signature; import net.sf.cglib.core.ReflectUtils; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Factory; // // Decompiled by Procyon v0.5.30 // //1enhancer代码生成器自动生成了类UserService$$EnhancerByCGLIB$$394dddeb继承了实现类UserService实现了接口Factory。 public class UserService$$EnhancerByCGLIB$$394dddeb extends UserService implements Factory { private boolean CGLIB$BOUND; private static final ThreadLocal CGLIB$THREAD_CALLBACKS; private static final Callback[] CGLIB$STATIC_CALLBACKS; private MethodInterceptor CGLIB$CALLBACK_0;//这里保存步骤4中通过enhancer.setCallback(new MyMethodInterceptor());传入的对象 private static final Method CGLIB$add$0$Method; private static final MethodProxy CGLIB$add$0$Proxy; private static final Object[] CGLIB$emptyArgs; static void CGLIB$STATICHOOK2() { CGLIB$THREAD_CALLBACKS new ThreadLocal(); CGLIB$emptyArgs new Object[0]; //通过反射机制获取代理类 final Class? forName Class.forName(UserService$$EnhancerByCGLIB$$394dddeb); final Class? forName3; //查找到实现类的add方法 CGLIB$add$0$Method ReflectUtils.findMethods(new String[] { add, ()V }, (forName3 Class.forName(UserService)).getDeclaredMethods())[0]; //创建MethodProxy对象每个被代理的方法都对应一个MethodProxy对象methodProxy.invokeSuper方法最终调用实现类的add方法 CGLIB$add$0$Proxy MethodProxy.create((Class)forName3, (Class)forName, ()V, add, CGLIB$add$0);//将代理类的两个代理方法传入 } //最终调用的方法是父类也就是实现类的方法add final void CGLIB$add$0() { super.add(); } public final void add() { MethodInterceptor cglib$CALLBACK_0; cglib$CALLBACK_0this. CGLIB$CALLBACK_0; //先判断拦截器对象MethodInterceptor是否为空不为空则执行回调intercept if (cglib$CALLBACK_0 ! null) { cglib$CALLBACK_0.intercept((Object)this, UserService$$EnhancerByCGLIB$$394dddeb.CGLIB$add$0$Method, UserService$$EnhancerByCGLIB$$394dddeb.CGLIB$emptyArgs, UserService$$EnhancerByCGLIB$$394dddeb.CGLIB$add$0$Proxy); return; } super.add(); } static { CGLIB$STATICHOOK2(); } } 1.4.3 Cglib代理的整体流程 详细步骤如下 1 定义实现类UserServiceImpl和拦截器MyMethodInterceptor拦截器实现intercept方法 2 创建Enhancer enhancer对象通过enhancer.setSuperclass(UserServiceImpl.class); 传入实现类的class作为代理类的父类。通过enhancer.setCallback(new MyMethodInterceptor()); //设置拦截器对象保存在代理类的cglib$CALLBACK_0属性中。提供回调代理类会调用MyMethodInterceptor的函数intercept函数返回调用 3 Enhancer是CGLib的字节码增强器生成代理类的代码代理类继承了实现类UserServiceImpl代理类实现了两个代理方法final void CGLIB$add$0()和public final void add()方法这里不知道为什么要这样设计。CGLIB$add$0()是最终调用的方法 4 创建代理类对象UserServiceImpl userService (UserServiceImpl)enhancer.create();userService.add()调用代理类的在步骤三中的public final void add()方法先判断cglib$CALLBACK_0对象是否为空。不为空则执行MethodInterceptor的回调函数cglib$CALLBACK_0.intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) 5 Intercept回调函数实现实际上调用了参数MethodProxy proxy的proxy.invokeSuper方法 public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { System.out.println(Before: method); Object object proxy.invokeSuper(obj, arg); System.out.println(After: method); return object; } 6 proxy又是从哪里来的呢步骤4中传入的实参是这样实现的 //创建MethodProxy对象每个被代理的方法都对应一个MethodProxy对象methodProxy.invokeSuper方法最终调用实现类的add方法 CGLIB$add$0$Proxy MethodProxy.create((Class)forName3, (Class)forName, ()V, add, CGLIB$add$0);//将代理类的两个代理方法传入 7 每个被代理的方法都对应一个MethodProxy对象methodProxy.invokeSuper方法最终调用实现类的add方法proxy.invokeSuper的内部的实现如下 public Object invokeSuper(Object obj, Object[] args) throws Throwable { try { init(); FastClassInfo fci fastClassInfo; return fci.f2.invoke(fci.i2, obj, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } } 实现方法中创建了一个FastClassInfo fci对象然后调用了fci.f2.invoke(fci.i2, obj, args); 8单看invokeSuper方法的实现似乎看不出实现类add方法调用在MethodProxy实现中通过FastClassInfo维护了实现类和代理类的FastClass。 private static class FastClassInfo { FastClass f1; FastClass f2; int i1; int i2; } 以add方法的methodProxy为例f1指向实现类对象f2指向代理类对象i1和i2分别是方法add和CGLIB$add$0在对象中索引位置。那么fci.f2.invoke(fci.i2, obj, args);的含义就是调用代理对象的invoke方法传入参数是代理类的实现方法CGLIB$add$0、代理对象、函数参数 9这样有回到了代理类中的方法CGLIB$add$0() final void CGLIB$add$0() { super.add(); } 10super是父类的意思指向的是实现类然后执行实现类的add方法。绕了一个好大的圈终于绕回来了。不知道什么原因要这样搞。 1.4.4 FastClass实现机制 FastClass其实就是对Class对象进行特殊处理提出下标概念index通过索引保存方法的引用信息将原先的反射调用转化为方法的直接调用从而体现所谓的fast下面通过一个例子了解一下FastClass的实现机制。 1、定义原类 class Test { public void f(){ System.out.println(f method); } public void g(){ System.out.println(g method); } } 2、定义Fast类 class FastTest { public int getIndex(String signature){ switch(signature.hashCode()){ case 3078479: return 1; case 3108270: return 2; } return -1; } public Object invoke(int index, Object o, Object[] ol){ Test t (Test) o; switch(index){ case 1: t.f(); return null; case 2: t.g(); return null; } return null; } } 在FastTest中有两个方法getIndex中对Test类的每个方法根据hash建立索引invoke根据指定的索引直接调用目标方法避免了反射调用。所以当调用methodProxy.invokeSuper方法时实际上是调用代理类的CGLIB$add$0方法CGLIB$add$0直接调用了实现类的add方法。 自己编了一个股票监控软件有如下功能有兴趣的朋友可以下载 1 个股监测。监测个股实时变化可以监测个股大单交易、急速拉升和下降、主力入场和出场、股票最高点和最低点提醒。检测到最高点、最低点、主力进场点、主力退场点、急速拉升点、急速下跌点给出语音或者声音提醒不用再时刻看着大盘了给你更多自由的时间 2 大盘监测。监测大盘的走势采用上证、深证、创业三大指数的综合指数作为大盘走势。并实时监测大盘的最高点和最低点、中间的转折点。 3 股票推荐。还能根据历史数据长期或短期走势进行分析对股市3千多个股票进行分析对比选出涨势良好的股票按照增长速度从大到小排序推荐给你涨势良好的股票 下载地址 1.0.3版本修复大盘指数崩溃缺陷下载地址 链接https://pan.baidu.com/s/1BJcTp-kdniM7VE9K5Kd3vg 提取码003h 更新链接 https://www.cnblogs.com/bclshuai/p/10621613.html转载于:https://www.cnblogs.com/bclshuai/p/10651959.html