代理模式
代码示例
package 设计模式.代理模式.静态代理; public class Demo { public static void main(String[] args) { DogProxy dogProxy = new DogProxy(new Dog()); dogProxy.voice(); } static class DogProxy implements Animal{ private Dog dog; public DogProxy(Dog dog) { this.dog = dog; } @Override public void voice() { System.out.println("执行方法前..."); dog.voice(); System.out.println("执行方法后..."); } } static class Dog implements Animal { @Override public void voice() { System.out.println("汪汪汪..."); } } interface Animal{ void voice(); } }
public class DynamicProxy { // 动态代理 public static void main(String[] argsx) { final Cat cat = new Cat(); /** * 三个参数(被代理类的ClassLoader, 实现的接口的数组, InvocationHandler接口的实现) */ Animal catProxy = (Animal)Proxy.newProxyInstance(Cat.class.getClassLoader(), new Class[]{Animal.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName()+"-方法-------start-------"); Object invoke = method.invoke(cat, args); System.out.println(method.getName()+"-方法-------end-------"); return invoke; } }); catProxy.voice(); } // 被代理的类 static class Cat implements Animal{ @Override public void voice() { System.out.println("喵喵喵..."); } } // 被代理的类的接口 interface Animal{ void voice(); } }
public class CglibProxy { public static void main(String[] args) { // 1.生成一个增强器 Enhancer enhancer = new Enhancer(); // 2.被代理的类设置成父类 enhancer.setSuperclass(Cat.class); // MethodInterceptor拦截器,相当于jdk的InvokeHandler enhancer.setCallback(new MethodInterceptor() { /** * 代理增强的实现 * @param o cglib生成的一个类,继承至被代理的类 * @param method 代理的方法 * @param objects 参数 * @param methodProxy 方法代理 * @throws Throwable */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println(method.getName()+"------执行前-----"); Object result = methodProxy.invokeSuper(o, objects); System.out.println(method.getName()+"------执行后-----"); return result; } }); Cat cat = (Cat)enhancer.create(); cat.voice(); } // 被代理的类 static class Cat{ public void voice() { System.out.println("喵喵喵..."); } } }
jdk动态代理与cglib动态代理的区别
jdk动态代理被代理的类必须有实现接口,利用拦截器和反射机制生成代理接口的匿名类,在调用具体方法前调用InvokeHandler来进行处理
cglib是基于ASM框架修改字节码生成子类进行处理的,因为是继承,所以被final类不能使用cglib进行代理
作者:[一柒微笑]