Java代理模式根据代理类生成时间的不同,可以分为静态代理和动态代理,它如同中介机构,可以为目标类提供代理服务,以控制对对象的访问,目标类的任何方法在执行前都必须经过代理类,这样代理类就可以用来负责请求的预处理、过滤、将请求分派给目标类处理、以及目标类执行完请求后的后续处理。这在实际开发和框架设计(如springAOP)中有着广泛的应用.
1.静态代理public interface Task { public void execute(); }
public class TaskImpl implements Task{ public void execute() { System.out.println("执行任务"); } }
public class TaskProxy implements Task { private Task taskImpl; public TaskProxy(Task taskImpl) { this.taskImpl = taskImpl; } public void execute() { System.out.println("任务执行之前"); //调用目标类的方法 taskImpl.execute(); System.out.println("任务执行之后"); } public static void main(String[] args) { Task taskImpl = new TaskImpl(); TaskProxy taskProxy = new TaskProxy(taskImpl); taskProxy.execute(); } }静态代理的实现很简单,但是也有其不足:一个代理类只能为一个接口服务,如果要代理的方法很多,那就必须为每一个方法进行代理,如果接口增加一个方法,不仅目标类要实现这个方法,而且代理类也要做相应的修改,代码的维护就会变的复杂很多,如果要代理不同的接口,那就需要实现多个代理类,使得代码的复用性很差.而动态代理则能够通过反射机制等实现一个代理类完成全部的代理功能,降低了代码间的耦合度和维护时的复杂度.
public class TaskDynamicProxy implements InvocationHandler { private Object target; //绑定委托对象并返回一个代理类 public Object bind(Object target) { this.target = target; //取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } 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; } public static void main(String[] args) { TaskDynamicProxy proxy2 = new TaskDynamicProxy(); Task task = (Task) proxy2.bind(new TaskImpl()); task.execute(); } }
B.cglib动态代理代码:
public class TaskProxyCglib 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(); } public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy proxy) throws Throwable { System.out.println("任务开始执行之前"); proxy.invokeSuper(arg0, arg2); System.out.println("任务开始执行之后"); return null; } public static void main(String[] args) { TaskProxyCglib cglib = new TaskProxyCglib(); TaskImpl taskImpl = (TaskImpl) cglib.getInstance(new TaskImpl()); taskImpl.execute(); } }