java 代理的三种实现方式
Java 代理模式有如下几种实现方式: 1.静态代理。 ? ? ? 2.JDK动态代理。 ? ? ? 3.CGLIB动态代理。 ? 示例,有一个打招呼的接口。分别有两个实现,说hello,和握手。代码如下。 接口: public interface Greeting { void doGreet(); } 实现类: class SayHello implements Greeting { @Override doGreet() { System.out.println("Greeting by say 'hello' ."); } } class ShakeHands doGreet() { System.out.println("Greeting by shake others's hands ."class KissHello { doGreet() { System.out.println("Greeting by kiss . "); } } ? 在不改变代码的情况下,想在执行目标方法 前后 做一些其他操作。则可以通过代理方式来实现。 1.静态代理。需要创建代理类。代理类实现了和目标类一样的接口,代理类接收目标类对象,并在实现方法中调用目标类的实现方法前后做手脚。如下: class GreetStaticProxy private Greeting hello;//被代理对象 public GreetStaticProxy(Greeting hello){ this.hello=hello; } @Override doGreet() { before();//执行其他操作 this.hello.doGreet();//调用目标方法 after();//执行其他操作 } before(){ System.out.println("[StaticProxy] Come to someone."); } after(){ System.out.println("[StaticProxy] Back to his own corner"); } } 测试调用: Main { static main(String[] args) { Greeting hello=new SayHello(); Greeting shakeHands= ShakeHands(); //静态代理 GreetStaticProxy staticHelloProxy= GreetStaticProxy(hello); staticHelloProxy.doGreet(); System.out.println(); GreetStaticProxy shakeHandsProxy= GreetStaticProxy(shakeHands); shakeHandsProxy.doGreet(); } 运行结果: 这个方式有弊端,如果有N个接口的实现类需要被代理,则需要创建N个代理类。 2.JDK动态代理 创建代理类,如下: class JdkProxy InvocationHandler { Object target; JdkProxy(Object obj){ this.target=obj; } @Override Object invoke(Object proxy,Method method,Object[] args) throws Throwable { Object result=null; before(); result=method.invoke(target,args); after(); return result; } before(){ System.out.println("[JdkProxy] Come to someone." after(){ System.out.println("[JdkProxy] Back to his own corner" ShakeHands(); jdk动态代理 JdkProxy dynamicProxy= JdkProxy(hello); Greeting target=(Greeting) Proxy.newProxyInstance(hello.getClass().getClassLoader(),hello.getClass().getInterfaces(),dynamicProxy); target.doGreet(); System.out.println(); } } 这种方式和第一种方式相比,虽然不需要创建很多代理类, 但是,他依赖与“被代理的对象需要实现接口” 即:在上面给出的代码示例中,动态代理可以代理SayHello和ShakeHands,却不能代理KissHello。因为KissHello没有实现接口。 3.CGLIB动态代理。 创建代理类: class CglibProxy MethodInterceptor { static CglibProxy proxy= CglibProxy(); CglibProxy(){} static CglibProxy getInstance(){ proxy; } public <T> T getProxy(Class<T> cls){ return (T) Enhancer.create(cls,); } @Override Object intercept(Object obj,Object[] arg,MethodProxy proxy) Throwable { Object result=; try { before(); result= proxy.invokeSuper(obj,arg); after(); } catch (Exception e) { e.printStackTrace(); } result; } before(){ System.out.println("[cglib] Come to someone." after(){ System.out.println("[cglib] Back to his own corner."); } } 调用示例: main(String[] args) { cglib代理 Greeting targetProxy=CglibProxy.getInstance().getProxy(SayHello.); targetProxy.doGreet(); System.out.println(); CglibProxy.getInstance().getInstance().getProxy(KissHello.).doGreet(); } } ? 综上,CGLIB动态代理最好,spring框架也用到了CGLIB包。 ? (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |