前面学习的都是静态代理,现在学习了动态代理。
一动态代理:
什么是动态代理:简单理解为一个通用的静态代理,即我不需要知道要代理谁,不管是谁需要代理我都可以在需要的时候进行代理。不管你是小学生,还是大学生,还是上班族,只要你需要代理,OK找我都可以代理。
二编写动态代理:
JDK提供了动态代理的接口,编写一个动态代理需要一个handler,然后再通过Proxy来产生代理对象。
首先编写HomeWorkHI:
package test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
*
* 每一个动态代理都有一个handler,这个handler用来产生代理类的对象,handler类的
* invoke方法实现了接口中的所有的抽象方法
*
*/
public class HomeWorkHI implements InvocationHandler {
//需要被代理的对象,在这里是小学生
private Object target = null;
public HomeWorkHI(Object _target) {
this.target = _target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = method.invoke(this.target, args);
return result;
}
}
这个handler所能处理的对象是所有的对象,不像前面都是指定好的对象。
然后修改场景类:
package test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] agrs) {
//定义一个小学生
Student primaryStudent = new PrimaryStudent("小明");
//定义一个handler,用于接管所有的小学生的方法
InvocationHandler handler = new HomeWorkHI(primaryStudent);
//定义一个类的加载器,这里为小学生类的加载器
ClassLoader classLoader = primaryStudent.getClass().getClassLoader();
//根据参数产生一个代理类
Student proxy = (Student)Proxy.newProxyInstance(classLoader, new Class[]{Student.class}, handler);
//调用方法
proxy.doHomeWork();
}
}
这里就简单实现了一个动态代理。
以下部分摘自《设计模式之禅》,通用动态代理的编写。
抽象主题:
public interfacr Subject {
//业务逻辑
public void doSomething(String str);
}
</pre><p></p><p>真实主题:</p><p></p><p><pre name="code" class="java">public class RealSubject implements Subject {
//业务操作
public void doSomething(String str) {
<span style="white-space:pre"> </span>System.out.println("do something...");
}
}
动态的handler类
package test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
//被代理的对象
private Object target = null;
public MyInvocationHandler(Object _target) {
this.target = _target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(target, args);
}
}
动态代理类
package test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class DynamicProxy {
public static <T> T newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) {
if(true) {
//执行一个前置通知
(new BeforeAdvice()).exec();
}
//执行目标并返回结果
return (T)Proxy.newProxyInstance(loader, interfaces, h);
}
}
通知接口类:
package test;
public interface IAdvice {
//通知只有一个方法,执行就行
public void exec();
}
package test;
public class BeforeAdvice implements IAdvice {
@Override
public void exec() {
System.out.println("我是前置通知,我被执行了");
}
}
场景类:
package test;
import java.lang.reflect.InvocationHandler;
public class Client2 {
public static void main(String[] args) {
//定义一个主题
Subject subject = new RealSubject();
//定义一个handler
InvocationHandler handler = new MyInvocationHandler(subject);
//定义主题的代理
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
//代理行为
proxy.doSomething("Finish");
}
}
扩展DynamicProxy:
package test;
import java.lang.reflect.InvocationHandler;
public class SubjectDynamicProxy extends DynamicProxy {
public static <T> T newProxyInstance(Subject subject) {
//获得loader
ClassLoader loader = subject.getClass().getClassLoader();
//获得接口数组
Class<?>[] classes = subject.getClass().getInterfaces();
//获得handler
InvocationHandler handler = new MyInvocationHandler(subject);
return newProxyInstance(loader,classes,handler);
}
}
修改后的场景类:
package test;
public class Client2 {
public static void main(String[] args) {
//定义一个主题
Subject subject = new RealSubject();
//定义主题的代理
Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);
proxy.doSomething("Finish");
}
}
以上为动态代理,也有一些AOP。