动态代理模式不需要代理类与目标类实现相同接口或继承相同类。动态代理也叫JDK代理或者接口代理,是利用JDK的API,动态的在内存中构建代理对象。代理类所在的包是java.lang.reflect.Proxy,动态代理只需要使用Proxy类的newProxyInstance方法即可完成,该方法有三个类型的必须的参数:
ClassLoader loader:目标对象的类加载器。
Class<?>[] interfaces:目标对象实现的接口类型。
InvocationHandler h:事件处理器,在执行目标对象的方法时,会触发事件处理器的invoke方法,把目标对象的方法作为参数传入:
proxy:代表代理实例;
method:代表在代理实例上调用的接口方法名称;
args:代表代理实例上调用的方法的参数列表;
Object类型的返回值即是代理对象。
动态代理案例如下:
接口:
package proxy.dynamicProxy;
public interface UserDao {
void buy(double money);
}
实现类:
package proxy.dynamicProxy;
public class UserDaoImpl implements UserDao {
public void buy(double money) {
System.out.println("厂家收到的货款是: " + money);
}
}
动态代理代码:
package proxy.dynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
//目标对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
//为目标对象生成代理对象
public Object getProxyInstance(double money) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
double money = Double.parseDouble(args[0].toString());
System.out.println("代理商赚取了20%的利润,利润总值为: " + money * 0.2);
Object result = method.invoke(target, money * 0.8);
return result;
}
});
}
}
测试类:
package proxy.dynamicProxy;
public class Test {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
ProxyFactory proxyFactory = new ProxyFactory(userDao);
//客户出价9000买电脑
System.out.println("客户出价9000购买笔记本电脑,9000元交到代理商手里");
double money = 9000.0;
//获取代理对象, proxyFactory.getProxyInstance(money)返回的是userDao的代理对象
userDao = (UserDao) proxyFactory.getProxyInstance(money);
userDao.buy(money);
}
}
运行结果:
动态代理模式完成。