代码篇 Java 实现代理模式( 二 )


jdk动态代理
我们首先来讲Jdk动态代理的实现,然后通过和CGLib的不同引入CGLib动态代理 。老套路,直接粘贴代码 。
动态代理代码:
package com.blaze.study.aop.dynamic;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class DynamicProxyDemo06 implements InvocationHandler{private Object target;public DynamicProxyDemo06(Object target){this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {operator1();Object result = method.invoke(target,args);operator2();return result;}public void operator1(){System.out.println("添加的操作1");}public void operator2(){System.out.println("添加的操作2");}}
这里我们通过实现接口,并且提供其方法的实现,就可以为所欲为,动态代理任何我们想要代理的类 。
接下面,通过一段使用者来阐述一些动态代理代码上的优化 。
package com.blaze.study.aop.dynamic;import com.blaze.study.aop.proxy.Hello;import com.blaze.study.aop.proxy.HelloImp;import java.lang.reflect.Proxy;public class DynamicProxyTestDemo06 {public static void main(String[] args) {Hello h = new HelloImp();DynamicProxyDemo06 dy = new DynamicProxyDemo06(h);Hello hello = (Hello)Proxy.newProxyInstance(h.getClass().getClassLoader(),h.getClass().getInterfaces(),dy);hello.say("Sherlock");}}
我们通过Proxy.来生成Hello的引用并且使用通过类型转换最后来调用say方法 。
根据在使用层面代码越简单越好的原则,我们通过可以通过在类中添加这样的方法来改造我们的动态代理类 。
@SuppressWarnings("unchecked")public T getProxy() {return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}
我们通过范型来完成类型的匹配,而不需要在调用者中使用强制方式的来进行类型转换 。
这个时候,我们就可以在调用者中通过下面的简单代码来调用被调用的方法 。
package com.blaze.study.aop.dynamic;import com.blaze.study.aop.proxy.Hello;import com.blaze.study.aop.proxy.HelloImp;public class DynamicProxyTestDemo06 {public static void main(String[] args) {Hello h = new DynamicProxyDemo06(new HelloImp()).getProxy();h.say("Sherlock");}}
动态代理跟静态代理的区别就是在动态代理中我们不需要为每一个类写一个代理类 。我们仅仅通过这一个类来代理我们想要代理的任何类 。比如我们有一个World接口、和World实现类 。
World.java

代码篇  Java 实现代理模式

文章插图
package com.blaze.study.aop.proxy;public interface World {void say(String word);}
.java
package com.blaze.study.aop.proxy;public class WorldImpl implements World{@Overridepublic void say(String word) {System.out.println(word + "\tWorld!");}}
这样我们通过代码调用代理的服务,并且添加我们的操作,简单轻松 。
package com.blaze.study.aop.dynamic;import com.blaze.study.aop.proxy.Hello;import com.blaze.study.aop.proxy.HelloImp;import com.blaze.study.aop.proxy.World;import com.blaze.study.aop.proxy.WorldImpl;public class DynamicProxyTestDemo06 {public static void main(String[] args) {Hello h = new DynamicProxyDemo06(new HelloImp()).getProxy();h.say("Sherlock");/**新的被代理类*/World w = new DynamicProxyDemo06(new WorldImpl()).getProxy();w.say("Blaze");}}
CGLib动态代理
接下面要讲的动态代理实现的方式就是CGLib,CGLib博大精深,这篇文章里我们就完成一个简单的实现 。JDK动态代理必须要我们的被代理类有一个接口,如果没有接口,就会报类型转化错误 。