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();
}
}
静态代理的实现很简单,但是也有其不足:一个代理类只能为一个接口服务,如果要代理的方法很多,那就必须为每一个方法进行代理,如果接口增加一个方法,不仅目标类要实现这个方法,而且代理类也要做相应的修改,代码的维护就会变的复杂很多,如果要代理不同的接口,那就需要实现多个代理类,使得代码的复用性很差.而动态代理则能够通过反射机制等实现一个代理类完成全部的代理功能,降低了代码间的耦合度和维护时的复杂度.2.动态代理
动态代理常用的实现方式有JDK动态代理和cglib动态代理,JDK动态代理通过反射机制来实现代理功能,但只能代理实现了接口的类,而没有实现接口的类可以通过cglib来代理.cglib动态代理的原理是对目标类生成一个子类,并覆盖其中的方法,但是有final修饰的类由于不能继承故cglib不能进行代理.
A.JDK动态代理代码:
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();
}
}