代理模式是java中一种很常见的设计模式,在企业应用高级框架中经常会用到,它的原理就是使用反射来完成。
为什么要使用代理?在某些情况在,一个客户不想或不能直接引用另一个对象,需要通过代理对象来间接操作目标对象,代理就是在客户端和目标对象之间起到中介作用。
举个例子来说明,一个客户想找厂家生产一批衣服,但客户找不到合适的厂家,只能找中介来帮它找厂家生产。
首先说明的是代理有两种形式,一是静态代理,一是动态代理。静态代理不需要用到反射,如下列说明:
package reflection;
/**
* 静态代理实例
* @author kepu
*
*/
public class staticAgent {
public static void main(String[] args) {
Customer customer=null;
customer=new Customer();
}
}
//服装厂接口
interface ClothingFactory{
//有成产衣服的功能
public void productClothing();
}
//adidas是一家能够正真生产衣服的厂家
class adidasFactory implements ClothingFactory{
@Override
public void productClothing() {
System.out.println("adidas厂生产了衣服");
}
}
//一家可以帮客户找服装厂的中介公司
class ProxyCompany implements ClothingFactory{
private ClothingFactory cf;//中介公司认识的的服装厂资源
public ProxyCompany(ClothingFactory cf) {
this.cf=cf;
}
@Override
public void productClothing() {
System.out.println("中介公司收取中介费用");
cf.productClothing();//把订单交给实际能生产衣服的厂家
}
}
//需要定制一批衣服的客户
class Customer{
public Customer() {
//通过中介公司找到服装厂来生产衣服
ClothingFactory cf=new ProxyCompany(new adidasFactory());
cf.productClothing();
}
}
静态代理模式的特征是代理类和目标对象的类都是编译期间就已经知道的,就是说,代理机构已经准备好把生产衣服的厂家介绍给客户了,可如果客户想要生产别的,如鞋子什么的,代理机构还要再继续写出代理鞋厂的方法,很不方便。而使用动态代理就很方便了,代理类会根据客户提出的需求找到对应的生产厂家,而不需提前准备好把各种厂家介绍给客户。如下面例子所示:
package reflection;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理示例
* @author kepu
*
*/
//服装厂接口
interface ClothingFactory2{
//有成产衣服的功能
public void productClothing2();
}
//adidas是一家能够正真生产衣服的厂家
class adidasFactory2 implements ClothingFactory2{
@Override
public void productClothing2() {
System.out.println("adidas厂生产了衣服");
}
}
//鞋厂接口
interface ShoesFactory2{
public void productShoes();
}
//特步是一家能真正生产鞋子的厂家
class TebuFactory2 implements ShoesFactory2{
@Override
public void productShoes() {
System.out.println("特步生产了鞋子");
}
}
/*//代理类的抽象类
interface InvoccationHandler{
public Object invoke(Object object,Method method,Object[] args)throws Throwable;
* 第一参数指代理类
* 第二个参数指被代理方法的Class对象
* 第三个参数指该方法的参数值数组
}*/
//动态代理处理类
class DynaxyHandler implements InvocationHandler{
//目标对象
private Object target;
//创建一个目标对象的代理对象
public Object newProxyInstane(Object target) {
this.target=target;
return Proxy.newProxyInstance(this.target.getClass().getClassLoader(),
this.target.getClass().getInterfaces(), this);
/**
* 第一个参数:定义代理类的加载器
* 第二个参数:代理类要实现的接口列表
* 第三个参数:指派方法调用的调用处理程序
*/
}
@Override
public Object invoke(Object object, Method method, Object[] args)
throws Throwable {
Object result=null;
//目标对象的方法调用之前可以添加其他代码
result=method.invoke(this.target, args);//通过反射来调用目标对象上对应的方法
//目标对象上的方法调用之后可以添加其他代码
return result;//把方法的返回值返回给调用者
}
}
class Customer2{
public Customer2() {
DynaxyHandler handler=new DynaxyHandler();
ClothingFactory2 cf2=(ClothingFactory2) handler.newProxyInstane(new adidasFactory2());
cf2.productClothing2();
ShoesFactory2 sf2=(ShoesFactory2) handler.newProxyInstane(new TebuFactory2());
sf2.productShoes();
}
}
public class DynamicAgent {
public static void main(String[] args) {
Customer2 customer=null;
customer=new Customer2();
}
}