1.代理模式的理解
1.1 代理模式的作用
代理模式的作用是通过代理对象来增强目标对象的功能。利用的是AOP横切的思想。
1.2 代理模式的实现方式
代理模式的实现方式有三种:静态代理,动态代理(JDK动态代理和CGLIB动态代理)
1.2.1 静态代理
我们先声明接口和目标实现类
/** * 定义公共接口 */ public interface SomeService { String doSome(); } 复制代码
目标类
/** * 目标对象 target */ public class SomeServiceImpl implements SomeService { @Override public String doSome() { System.out.println("目标对象:doSome()" ); return "hello ..."; } } 复制代码
然后创建对应的代理类
/** * 代理类 * 增强实现类 * 和实现类实现同一个接口 */ public class SomeProxy implements SomeService{ private SomeService target; public SomeProxy(SomeService target){ this.target = target; } /** * 增强的方法 * @return */ @Override public String doSome() { System.out.println("目标方法执行之前..."); String s = target.doSome(); System.out.println("目标方法执行之后..."); return s.toUpperCase(); } } 复制代码
然后测试实现
public class MainTest { public static void main(String[] args) { SomeService some = new SomeServiceImpl(); SomeProxy proxy = new SomeProxy(some); System.out.println(proxy.doSome()); } } 复制代码
对应的输出结果
目标方法执行之前... 目标对象:doSome() 目标方法执行之后... HELLO ... 复制代码
可以看到代理对象实现了目标对象的调用,同时增强了目标对象的功能。
1.2.2 JDK动态代理
上面的静态代理我们需要手动的创建一个对应的代理来实现,不是太灵活,针对目标对象有实现相关接口的情况,我们可以使用JDK动态代理。
public class JdkDynamicProxy { /** * JDK动态代理:目标对象必须实现相关的接口 * @param args */ public static void main(String[] args) { SomeService target = new SomeServiceImpl(); SomeService proxy = (SomeService) Proxy.newProxyInstance(JdkDynamicProxy.class.getClassLoader(), // 类加载器 target.getClass().getInterfaces() // 目标对象实现的相关接口 , new InvocationHandler() { // 代理对象的回调方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before..."); Object invoke = method.invoke(target, args); System.out.println("end..."); if (invoke != null) { return invoke.toString().toUpperCase(); } return null; } }); // 通过代理对象来执行 System.out.println("proxy.doSome() = " + proxy.doSome()); } } 复制代码
输出结构
before... 目标对象:doSome() end... proxy.doSome() = HELLO ... 复制代码
3.2.3 CGLIB动态代理
如果目标对象实现了对应的接口我们可以通过JDK动态代理的方式来实现,但如果目标对象没有实现任何的接口,这时我们只能通过CGLIB动态代理来实现了,这时我们需要单独引入cglib的依赖
public class CGLIBDynamicProxy { /** * CGLIB动态代理 * @param args */ public static void main(String[] args) { SomeService target = new SomeServiceImpl(); SomeServiceImpl proxy = new MethodInterceptor() { /** * 创建 CGLIB 代理对象的方法 * @return */ public SomeServiceImpl createProxy() { // 创建增强器 Enhancer e = new Enhancer(); // 指定父类 e.setSuperclass(target.getClass()); // 指定回调接口对象 e.setCallback(this); // 创建CGLIB代理对象 return (SomeServiceImpl) e.create(); } /** * 拦截回调的方法 */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib -- befor" ); Object res = method.invoke(target, args); System.out.println("cglib -- end"); return res.toString().toUpperCase(); } }.createProxy(); System.out.println("proxy.doSome() = " + proxy.doSome()); } } 复制代码
输出的结果
cglib -- befor 目标对象:doSome() cglib -- end proxy.doSome() = HELLO ...