java 代理模式
java 的代理有两种实现方式,1、利用java jdk自带的反射实现,InvocationHandler,2、cglib 实现的动态代理
1、JDK 实现
1.1 描述
java 的动态代理 是通过 Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h) 方法生成一个代理对象对目标对象进行增强,增强的实现在InvocationHandler 中的invoke 方法实现
1.2 代码实现(用户通过某猪网购买车票)
public class JavaProxyFactory { /** * 代理工厂 * @param target * @return */ public static Object getProxyFactory(final Object target){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("在某猪网找到了。。。。"); Object returnObject = method.invoke(target,args); System.out.println("在某猪网购买了。。。。"); return null; } }); } /** * 购买车票的接口 */ interface BuyTicketService{ void buy(); } /** * 用户购买车票实现 */ static class UserBuyTicket implements BuyTicketService{ public void buy( ) { System.out.println("用户购买了火车票"); } } public static void main(String[] args) { BuyTicketService buyTicketService = (BuyTicketService ) JavaProxyFactory.getProxyFactory(new UserBuyTicket()); buyTicketService.buy(); } }
----------- 打印结果------
在某猪网找到了。。。。
用户购买了火车票
在某猪网购买了。。。。
2、cglib 实现
2.1 描述
cglib 实在编译时增强
2.2 代码实现
第一步添加依赖
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
public class CgLibProxyFactory implements MethodInterceptor { private Object obj; public Object createCgLibProxyObj(Object object){ this.obj = object; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(obj.getClass()); enhancer.setCallback(this); return enhancer.create(); } /** * * @param o 代理类本身 * @param method 目标类方法 * @param objects 目标类方法参数 * @param methodProxy 代理类的代理方法 * @return * @throws Throwable */ public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("在某猪网找到了。。。。"); Object returnObject = method.invoke(obj,objects); System.out.println("在某猪网购买了。。。。"); return returnObject; } /** * 用户购买车票实现 */ static class UserBuyTicket { public void buy( ) { System.out.println("用户购买了火车票"); } } public static void main(String[] args) { //目标对象 UserBuyTicket userBuyTicket = ( UserBuyTicket )new CgLibProxyFactory() .createCgLibProxyObj(new UserBuyTicket()); userBuyTicket.buy(); }
-----打印结果
在某猪网找到了。。。。
用户购买了火车票
在某猪网购买了。。。。
3、两者比较
JKD代理 | 1、运行时增强编译快jar包太大时可选; | 1、运行时增强执行效率相对较低;2、实现必须依赖接口实现 |
CGLIB代理 | 1、编译时增强,jar包不大时可选;2、任何类都可以实现,无需依赖接口 | 1、编译时增强,执行效率高 |