多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## Java专题九(2):动态代理 [TOC] #### JDK静态代理 > 使用接口代理实现类的方法调用 定义一个接口 ~~~ public interface HelloService { void sayHello(); } ~~~ 定义一个实现类 ~~~ public class HelloServiceImpl implements HelloService{ @Override public void sayHello() { System.out.println("say hello..."); } } ~~~ 测试代理方法 ~~~ public class HelloTest { public static void main(String[] args){ HelloService hello = new HelloServiceImpl(); hello.sayHello(); } } ~~~ 输出 ~~~ say hello... ~~~ #### JDK动态代理 - 可以隐藏委托类 - 在不修改委托类代码的情况下,可以为委托类的方法增加一些操作,如方法中实际代码前后增加日志输出 > 首先通过Proxy为委托类创建代理对象,将代理对象上对方法的调用通过`InvocationHandler`分发给实际的委托类调用,只能为实现了接口的类提供代理。 定义一个接口 ~~~ public interface HelloService { void sayHello(); } ~~~ 定义一个委托类,实现接口 ~~~ public class HelloServiceImpl implements HelloService{ @Override public void sayHello() { System.out.println("say hello..."); } } ~~~ 创建代理类,必须实现`InvocationHandler`接口 ~~~ public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; } ~~~ ~~~ // java.lang.reflect.Proxy public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h){ // ... } ~~~ ~~~ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class HelloServiceProxy implements InvocationHandler { private Object target; public Object bind(Object target){ this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before invoked..."); Object result = method.invoke(target, args); System.out.println("before invoked..."); return result; } } ~~~ 测试代理方法 ~~~ public class HelloTest { public static void main(String[] args){ HelloServiceProxy helloServiceProxy = new HelloServiceProxy(); HelloService proxy = (HelloService) helloServiceProxy.bind(new HelloServiceImpl()); proxy.sayHello(); } } ~~~ 输出 ~~~ before invoked... say hello... before invoked... ~~~ #### CGLIB动态代理 HelloServer.java和HelloServiceImpl.java都不用改变, ~~~ public class HelloServiceCglib implements MethodInterceptor { private Object target; public Object getInstance(Object target){ this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperClass(this.target.getClass()); enhancer.setCallback(this); return enhancer.setCallback(this); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy porxy) throws Throwable { System.out.println("before invoked..."); Object returnObj = porxy.invokeSuper(obj, args); System.out.println("before invoked..."); return returnObj ; } } ~~~