java代理通俗简单解析
1???????? 代理
1.1??????????? 代理的概念和作用
代理的概念很好理解,就像黃牛代替票務(wù)公司給你提供票,經(jīng)紀(jì)人代理藝人和別人談合作。Java的代理是指實(shí)現(xiàn)類作為代理類的屬性對(duì)象,代理類提供方法給外部調(diào)用,代理類內(nèi)部再去調(diào)用實(shí)現(xiàn)類的方法,實(shí)現(xiàn)具體的業(yè)務(wù)。也就是代理類作為對(duì)外接口人,實(shí)現(xiàn)類不直接對(duì)外。這就是java代理的概念。
代理的作用是當(dāng)你需要增加一些而外的操作,而又不想去修改實(shí)現(xiàn)類的??梢酝ㄟ^(guò)代理來(lái)實(shí)現(xiàn),在代理類中增加附件的操作。例如需要增加權(quán)限過(guò)濾,但是業(yè)務(wù)類已經(jīng)開發(fā)好,不想將權(quán)限和業(yè)務(wù)混在一起,想讓每個(gè)類的功能盡可能單一,各司其職。,此時(shí)我們就可以做一個(gè)該類的代理類,由該代理類做權(quán)限判斷,如果安全則調(diào)用實(shí)際類的業(yè)務(wù)開始處理。
代理分為靜態(tài)代理和動(dòng)態(tài)代理,動(dòng)態(tài)代理有分為jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理。
1.2??????????? 靜態(tài)代理
先定義一個(gè)接口Subject,然后實(shí)現(xiàn)類RealSubject和代理類Proxy都繼承這個(gè)接口,實(shí)現(xiàn)接口的方法。代理類構(gòu)造函數(shù)的形參是接口引用Subject subject,實(shí)現(xiàn)類對(duì)象作為代理類構(gòu)造函數(shù)的實(shí)參傳入,保存到代理類的接口類型的Subject屬性中。用戶調(diào)用代理類的方法,代理類方法內(nèi)部通過(guò)接口引用再去調(diào)用實(shí)現(xiàn)類的方法。
//定義接口
interface Subject {
??? void request();
}
//實(shí)現(xiàn)類實(shí)現(xiàn)接口
class RealSubject implements Subject {
??? public void request(){
??????? System.out.println("RealSubject");
??? }
}
//代理類實(shí)現(xiàn)接口
class Proxy implements Subject {
??? private Subject subject;
?
??? public Proxy(Subject subject){//代理構(gòu)造函數(shù)接口形參,以實(shí)現(xiàn)類對(duì)象為實(shí)參
??????? this.subject = subject;
??? }
??? public void request(){
??????? System.out.println("begin");
??????? subject.request();//調(diào)用實(shí)現(xiàn)類的方法
??????? System.out.println("end");
??? }
}
//調(diào)用實(shí)例
public class ProxyTest {
??? public static void main(String args[]) {
?????? ?RealSubject subject = new RealSubject();//創(chuàng)建實(shí)現(xiàn)類對(duì)象
??????? Proxy p = new Proxy(subject);//創(chuàng)建代理類對(duì)象
??????? p.request();//調(diào)用代理類的方法,內(nèi)部再去調(diào)用實(shí)現(xiàn)類的request方法
??? }
}
1.3??????????? Jdk動(dòng)態(tài)代理
1.3.1???????????? Jdk動(dòng)態(tài)代理實(shí)現(xiàn)
Jdk動(dòng)態(tài)代理實(shí)際上是利用了java的反射機(jī)制。利用java.lang.reflect.Proxy類和java.lang.reflect.InvocationHandler接口定義代理類的實(shí)現(xiàn)。將實(shí)現(xiàn)類的接口信息傳入到代理類的靜態(tài)構(gòu)造函數(shù)Proxy.newProxyInstance中,代理類的構(gòu)造函數(shù)內(nèi)部通過(guò)反射的機(jī)制,獲取實(shí)現(xiàn)類的方法,代理類的代理方法對(duì)實(shí)現(xiàn)類的方法進(jìn)行了包裝。調(diào)用代理類的方法,內(nèi)部調(diào)用實(shí)現(xiàn)類的方法。實(shí)際上靜態(tài)代理和動(dòng)態(tài)代理本質(zhì)上是一樣的,只是動(dòng)態(tài)代理利用的反射的機(jī)制獲取實(shí)現(xiàn)類的方法。
(1)//定義實(shí)現(xiàn)類繼承的接口
public interface Service {?
??? //目標(biāo)方法
??? public abstract void add();?
}
(2)//實(shí)現(xiàn)類并繼承接口,實(shí)現(xiàn)方法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接口定義代理類的實(shí)現(xiàn)。重寫InvocationHandler的invoke方法。
class MyInvocatioHandler implements InvocationHandler {
??? private Object target;//接口屬性
??? public MyInvocatioHandler(Object target) {//構(gòu)造函數(shù),實(shí)參實(shí)現(xiàn)類對(duì)象
??????? 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;
??? }
??? // 生成代理對(duì)象方法
public Object getProxy() {
//獲取類加載器
??????? ClassLoader loader = Thread.currentThread().getContextClassLoader();
??? //獲取實(shí)現(xiàn)類的方法接口,提供反射機(jī)制的方法名稱
?Class<?>[] interfaces = target.getClass().getInterfaces();
//調(diào)用Proxy的靜態(tài)方法創(chuàng)建代理對(duì)象
??????? return Proxy.newProxyInstance(loader, interfaces, this);
??? }
}
(4)使用動(dòng)態(tài)代理實(shí)例
public class ProxyTest {
public static void main(String[] args) {
//創(chuàng)建實(shí)現(xiàn)類對(duì)象
??????? Service service = new UserServiceImpl();
//實(shí)現(xiàn)類對(duì)象以實(shí)參形式傳入代理類,保存在tartget屬性中
??????? MyInvocatioHandler handler = new MyInvocatioHandler(service);
//獲取代理對(duì)象
??????? Service serviceProxy = (Service)handler.getProxy();
????????????? //通過(guò)代理對(duì)象調(diào)用方法
??????? serviceProxy.add();//執(zhí)行方法
??? }
}
執(zhí)行結(jié)果:
?
-----before-----
This is add service
-----end-----
1.3.2???????????? Jdk動(dòng)態(tài)代理反推過(guò)程
從步驟(4)開始在逆向推到一遍。先創(chuàng)建一個(gè)實(shí)現(xiàn)類對(duì)象service,作為入?yún)鹘o??????? new MyInvocatioHandler(service);構(gòu)造函數(shù),保存在target屬性中。通過(guò)getProxy()方法創(chuàng)建代理對(duì)象。Proxy.newProxyInstance(loader, interfaces, this);入?yún)⒎謩e是loader加載類對(duì)象,interfaces實(shí)現(xiàn)類對(duì)象target的方法信息,this是MyInvocatioHandler指針。在newProxyInstance函數(shù)內(nèi)部通過(guò)反射機(jī)制,根據(jù)interfaces傳入的方法名稱等信息,獲取實(shí)現(xiàn)類的方法method。同時(shí)代理類內(nèi)部對(duì)實(shí)現(xiàn)類的每個(gè)方法都對(duì)應(yīng)實(shí)現(xiàn)了代理方法。serviceProxy.add();調(diào)用了代理類的代理方法,代理方法內(nèi)部通過(guò)調(diào)用MyInvocatioHandler的invoke方法,返回invoke(Object proxy, Method method, Object[] args)去調(diào)用實(shí)現(xiàn)類的Method。在invoke方法里面就可以增加其他的操作,比如說(shuō)日志打印;其中Method參數(shù)是通過(guò)反射機(jī)制,根據(jù)interfaces信息獲取到的實(shí)現(xiàn)類的方法。和靜態(tài)映射的原理差不多,只是將代理類進(jìn)行了包裝。
1.3.3???????????? jdk代理類源碼解析
為了更清楚的理解動(dòng)態(tài)代理,通過(guò)以下方式把代理類字節(jié)碼生成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?看看代理類如何實(shí)現(xiàn),反編譯出來(lái)的java代碼如下:
//代理類繼承extends類,和實(shí)現(xiàn)類一樣也實(shí)現(xiàn)了Service接口
public final class $proxy1 extends Proxy implements Service { //構(gòu)造函數(shù) ??? 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); ??????? } ??? } //這里調(diào)用的是實(shí)現(xiàn)類add代理方法 ?? ?public final void add() { ??????? try { //內(nèi)部調(diào)用的是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); ??????? } ??? } //定義靜態(tài)Method變量 ??? private static Method m1; ??? private static Method m2; ?? ?private static Method m3; ??? private static Method m0; //通過(guò)反射機(jī)制和interfaces提供的信息獲取實(shí)現(xiàn)類的方法 ??? 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]); //通過(guò)反射機(jī)制獲取實(shí)現(xiàn)類的方法 ??????? ????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??????????? 不用實(shí)現(xiàn)接口的Cglib代理
1.4.1???????????? Cglib代理的簡(jiǎn)單實(shí)現(xiàn)
靜態(tài)代理和jdk動(dòng)態(tài)代理都需要通過(guò)實(shí)現(xiàn)一個(gè)接口,只能對(duì)該類接口中定義的方法實(shí)現(xiàn)代理,這在實(shí)際編程中有一定的局限性。使用cglib[Code Generation Library]實(shí)現(xiàn)動(dòng)態(tài)代理,并不要求實(shí)現(xiàn)類必須實(shí)現(xiàn)接口。
使用步驟
(1)先定義實(shí)現(xiàn)類,實(shí)現(xiàn)方法add
public class UserServiceImpl {?
??? public void add() {?
??????? System.out.println("This is add service");?
??? }
}
(2)實(shí)現(xiàn)MyMethodInterceptor實(shí)現(xiàn)MethodInterceptor接口,定義方法的攔截器intercept方法,該對(duì)象會(huì)被傳入代理類中,相當(dāng)于回調(diào)函數(shù)的作用,代理類內(nèi)部調(diào)用intercept方法,intercept方法的四個(gè)參數(shù):1)代理對(duì)象;2)實(shí)現(xiàn)類方法;3)方法參數(shù);4)代理方法的MethodProxy對(duì)象。
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類生成代理類;創(chuàng)建Enhancer enhancer對(duì)象,將實(shí)現(xiàn)類作為入?yún)魅雃nhancer,作為代理類的父類。設(shè)置攔截器MyMethodInterceptor 到enhancer內(nèi)部,作為回調(diào)。
?
Enhancer enhancer = new Enhancer();//創(chuàng)建Enhancer類對(duì)象
enhancer.setSuperclass(UserServiceImpl.class); //傳入實(shí)現(xiàn)類的class,為反射提供信息 ,同時(shí)實(shí)現(xiàn)類是Enhancer的父類
enhancer.setCallback(new MyMethodInterceptor());? //設(shè)置攔截器對(duì)象,通過(guò)攔截器回調(diào)。Enhancer是CGLib的字節(jié)碼增強(qiáng)器,可以方便的對(duì)類進(jìn)行擴(kuò)展,內(nèi)部調(diào)用GeneratorStrategy.generate方法生成代理類。傳入了實(shí)現(xiàn)類作為父類,傳入MyMethodInterceptor對(duì)象,作為攔截回調(diào)。
UserServiceImpl userService = (UserServiceImpl)enhancer.create();//創(chuàng)建代理類對(duì)象,因?yàn)榇眍惱^承了實(shí)現(xiàn)類,所以可以用父類引用接收子類對(duì)象。
(4)userService.add();方法的執(zhí)行輸出結(jié)果。
Before: add
This is add service
After: add
1.4.2???????????? 代理類反向編譯源碼解析
對(duì)(UserServiceImpl)enhancer.create();返回的代理類進(jìn)行反向編譯,得到代理類的源碼如下。
這樣可能還是不能理解,代理類內(nèi)部是怎么實(shí)現(xiàn)的;
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
//
//(1)enhancer代碼生成器自動(dòng)生成了類UserService$$EnhancerByCGLIB$$394dddeb,繼承了實(shí)現(xiàn)類UserService,實(shí)現(xiàn)了接口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)中通過(guò)enhancer.setCallback(new MyMethodInterceptor());傳入的對(duì)象
??? 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];
//通過(guò)反射機(jī)制獲取代理類
??????? final Class<?> forName = Class.forName("UserService$$EnhancerByCGLIB$$394dddeb");
??????? final Class<?> forName3;
//查找到實(shí)現(xiàn)類的add方法
??????? CGLIB$add$0$Method = ReflectUtils.findMethods(new String[] { "add", "()V" }, (forName3 = Class.forName("UserService")).getDeclaredMethods())[0];
//創(chuàng)建MethodProxy對(duì)象,每個(gè)被代理的方法都對(duì)應(yīng)一個(gè)MethodProxy對(duì)象,methodProxy.invokeSuper方法最終調(diào)用實(shí)現(xiàn)類的add方法
??????? CGLIB$add$0$Proxy = MethodProxy.create((Class)forName3, (Class)forName, "()V", "add", "CGLIB$add$0");//將代理類的兩個(gè)代理方法傳入
}
//最終調(diào)用的方法是父類,也就是實(shí)現(xiàn)類的方法add
??? final void CGLIB$add$0() {
??????? super.add();
??? }
?
??? public final void add() {
????? MethodInterceptor cglib$CALLBACK_0;
???? cglib$CALLBACK_0=this. CGLIB$CALLBACK_0;
//先判斷攔截器對(duì)象MethodInterceptor是否為空,不為空則執(zhí)行回調(diào)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代理的整體流程
詳細(xì)步驟如下
(1)??? 定義實(shí)現(xiàn)類UserServiceImpl和攔截器MyMethodInterceptor,攔截器實(shí)現(xiàn)intercept方法;
(2)??? 創(chuàng)建Enhancer enhancer對(duì)象,通過(guò)enhancer.setSuperclass(UserServiceImpl.class); 傳入實(shí)現(xiàn)類的class,作為代理類的父類。通過(guò)enhancer.setCallback(new MyMethodInterceptor());? //設(shè)置攔截器對(duì)象,保存在代理類的cglib$CALLBACK_0屬性中。提供回調(diào)代理類會(huì)調(diào)用MyMethodInterceptor的函數(shù)intercept函數(shù)返回調(diào)用;
(3)??? Enhancer是CGLib的字節(jié)碼增強(qiáng)器,生成代理類的代碼,代理類繼承了實(shí)現(xiàn)類UserServiceImpl,代理類實(shí)現(xiàn)了兩個(gè)代理方法final void CGLIB$add$0()和public final void add()方法;這里不知道為什么要這樣設(shè)計(jì)。CGLIB$add$0()是最終調(diào)用的方法;
(4)??? 創(chuàng)建代理類對(duì)象UserServiceImpl userService = (UserServiceImpl)enhancer.create();userService.add();調(diào)用代理類的在步驟三中的public final void add();方法;先判斷cglib$CALLBACK_0對(duì)象是否為空。不為空,則執(zhí)行MethodInterceptor的回調(diào)函數(shù)cglib$CALLBACK_0.intercept(Object obj, Method method, Object[] arg, MethodProxy proxy);
(5)??? Intercept回調(diào)函數(shù)實(shí)現(xiàn)實(shí)際上調(diào)用了參數(shù)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又是從哪里來(lái)的呢,步驟(4)中傳入的實(shí)參是這樣實(shí)現(xiàn)的
//創(chuàng)建MethodProxy對(duì)象,每個(gè)被代理的方法都對(duì)應(yīng)一個(gè)MethodProxy對(duì)象,methodProxy.invokeSuper方法最終調(diào)用實(shí)現(xiàn)類的add方法
??????? CGLIB$add$0$Proxy = MethodProxy.create((Class)forName3, (Class)forName, "()V", "add", "CGLIB$add$0");//將代理類的兩個(gè)代理方法傳入
(7)??? 每個(gè)被代理的方法都對(duì)應(yīng)一個(gè)MethodProxy對(duì)象,methodProxy.invokeSuper方法最終調(diào)用實(shí)現(xiàn)類的add方法proxy.invokeSuper的內(nèi)部的實(shí)現(xiàn)如下
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();
??? }
}
實(shí)現(xiàn)方法中創(chuàng)建了一個(gè)FastClassInfo fci對(duì)象,然后調(diào)用了fci.f2.invoke(fci.i2, obj, args);
(8)單看invokeSuper方法的實(shí)現(xiàn),似乎看不出實(shí)現(xiàn)類add方法調(diào)用,在MethodProxy實(shí)現(xiàn)中,通過(guò)FastClassInfo維護(hù)了實(shí)現(xiàn)類和代理類的FastClass。
private static class FastClassInfo {
??? FastClass f1;
??? FastClass f2;
??? int i1;
??? int i2;
}
以add方法的methodProxy為例,f1指向?qū)崿F(xiàn)類對(duì)象,f2指向代理類對(duì)象,i1和i2分別是方法add和CGLIB$add$0在對(duì)象中索引位置。那么fci.f2.invoke(fci.i2, obj, args);的含義就是調(diào)用代理對(duì)象的invoke方法,傳入?yún)?shù)是代理類的實(shí)現(xiàn)方法CGLIB$add$0、代理對(duì)象、函數(shù)參數(shù);
(9)這樣有回到了代理類中的方法CGLIB$add$0()
final void CGLIB$add$0() {
??????? super.add();
}
(10)super是父類的意思,指向的是實(shí)現(xiàn)類,然后執(zhí)行實(shí)現(xiàn)類的add方法。繞了一個(gè)好大的圈終于繞回來(lái)了。不知道什么原因要這樣搞。
1.4.4???????????? FastClass實(shí)現(xiàn)機(jī)制
FastClass其實(shí)就是對(duì)Class對(duì)象進(jìn)行特殊處理,提出下標(biāo)概念index,通過(guò)索引保存方法的引用信息,將原先的反射調(diào)用,轉(zhuǎn)化為方法的直接調(diào)用,從而體現(xiàn)所謂的fast,下面通過(guò)一個(gè)例子了解一下FastClass的實(shí)現(xiàn)機(jī)制。
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中有兩個(gè)方法,getIndex中對(duì)Test類的每個(gè)方法根據(jù)hash建立索引,invoke根據(jù)指定的索引,直接調(diào)用目標(biāo)方法,避免了反射調(diào)用。所以當(dāng)調(diào)用methodProxy.invokeSuper方法時(shí),實(shí)際上是調(diào)用代理類的CGLIB$add$0方法,CGLIB$add$0直接調(diào)用了實(shí)現(xiàn)類的add方法。
?
自己編了一個(gè)股票監(jiān)控軟件,有如下功能,有興趣的朋友可以下載;
(1)?? 個(gè)股監(jiān)測(cè)。監(jiān)測(cè)個(gè)股實(shí)時(shí)變化,可以監(jiān)測(cè)個(gè)股大單交易、急速拉升和下降、主力入場(chǎng)和出場(chǎng)、股票最高點(diǎn)和最低點(diǎn)提醒。檢測(cè)到最高點(diǎn)、最低點(diǎn)、主力進(jìn)場(chǎng)點(diǎn)、主力退場(chǎng)點(diǎn)、急速拉升點(diǎn)、急速下跌點(diǎn),給出語(yǔ)音或者聲音提醒,不用再時(shí)刻看著大盤了,給你更多自由的時(shí)間;
(2)?? 大盤監(jiān)測(cè)。監(jiān)測(cè)大盤的走勢(shì),采用上證、深證、創(chuàng)業(yè)三大指數(shù)的綜合指數(shù)作為大盤走勢(shì)。并實(shí)時(shí)監(jiān)測(cè)大盤的最高點(diǎn)和最低點(diǎn)、中間的轉(zhuǎn)折點(diǎn)。
(3)?? 股票推薦。還能根據(jù)歷史數(shù)據(jù)長(zhǎng)期或短期走勢(shì)進(jìn)行分析,對(duì)股市3千多個(gè)股票進(jìn)行分析對(duì)比,選出漲勢(shì)良好的股票,按照增長(zhǎng)速度從大到小排序,推薦給你漲勢(shì)良好的股票;
下載地址:
1.0.3版本(修復(fù)大盤指數(shù)崩潰缺陷)下載地址:
鏈接:https://pan.baidu.com/s/1BJcTp-kdniM7VE9K5Kd3vg 提取碼:003h
更新鏈接:
https://www.cnblogs.com/bclshuai/p/10621613.html
轉(zhuǎn)載于:https://www.cnblogs.com/bclshuai/p/10651959.html
總結(jié)
以上是生活随笔為你收集整理的java代理通俗简单解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: idea自动生成not null判断语句
- 下一篇: redisTemplate.opsFor