代理模式是Java常见的设计模式,代理类和为拖类功能相同,代理类负责加强功能,代理类的对象自己并不真正实现服务,而是经过调用委托类的对象的相关方法,来提供特定的服务。 就像Spring Aop的实现,再特定方法执行前或后执行特定的拦截器,使用的就是动态代理。 代理分为两种: 静态代理:由程序员建立或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 动态代理:程序运行过程当中,由反射机制动态建立而成。java
下面分别讨论静态代理、jdk动态代理和cglib动态代理,Book.java和BookImpl.java为三种代理方法的公共类,直接上代码: 一、Book.java package com.proxy; public interface Book { //定义图书添加接口 public void addBook(); } 2.BookImpl.java package com.proxy; //委托类,包括业务逻辑 public class BookImpl implements Book{ @Override public void addBook() { System.out.println("添加图书"); } } 静态代理类: //这是一个代理类,加强BookImpl功能 public class BookProxy implements Book{程序员
private BookImpl bookImpl; public BookProxy(BookImpl bookImpl) { this.bookImpl = bookImpl; } @Override public void addBook() { System.out.println("代理前"); bookImpl.addBook(); System.out.println("代理后"); }
} Test.java public class Test { public static void main(String[] args) { BookProxy proxy = new BookProxy(new BookImpl()); proxy.addBook(); }编程
} 输出结果为: 代理前 添加图书 代理后 观察代码能够发现每个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,并且,全部的代理操做除了调用的方法不同以外,其余的操做都同样,则此时确定是重复代码。解决这一问题最好的作法是能够经过一个代理类完成所有的代理功能,那么此时就必须使用动态代理完成。 Jdk动态代理设计到一个接口和一个类: InvocationHandler接口: public interface InvocationHandler { public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; } Proxy类: Proxy类是专门完成代理的操做类,能够经过此类为一个或多个接口动态地生成实现类,此类提供了以下的操做方法: public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException 与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不只简化了编程工做,并且提升了软件系统的可扩展性,由于Java 反射机制能够生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力 jdk动态代理示例:设计模式
public class BookProxy implements InvocationHandler{ide
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 { Object result = null; System.out.println("代理前"); result = method.invoke(target, args); System.out.println("代理后"); return result; }
Test.java public class TestProxy {this
public static void main(String[] args) { BookFacadeProxy proxy = new BookFacadeProxy(); BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl()); bookProxy.addBook(); }
} } 输出结果为: 代理前 添加图书 代理后 可是,JDK的动态代理依靠接口实现,若是有些类并无实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。 Cglib动态代理 public class BookProxy 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.create(); } @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("代理前"); arg3.invokeSuper(arg0, arg2); System.out.println("代理后"); return null; }
} Test.java public class Test {代理
public static void main(String[] args) { BookProxy cglib = new BookProxy(); BookImpl bookCglib = (BookImpl) cglib.getInstance(new BookImpl()); bookCglib.addBook(); }
} 输出结果为: 代理前 添加图书 代理后code