静态模式:
1、抽象角色--接口
public interface Image {
void display();
}
2、具体的目标对象---被代理的对象
public class RealImage implements Image {
@Override
public void display() {
System.out.println("Displaying real image ");
}
}
3、代理对象,由于只能调用display方法,所以代理类也需要实现接口
public class ProxyImage implements Image{
private Image obj; --被代理的对象
public ProxyImage(Image target){
this.obj = target; }
public void display() {
System.out.println("前置处理,可以决定是否需要调用目标对象的方法");
obj.display(); }
}
4、测试调用
Image target=new RealImage();//创建目标对象,也就是被代理对象
Image proxy=new ProxyImage(target);//创建代理对象,同时注入被代理对象
proxy.display();从形式上看似乎调用的是代理对象的方法,但是事实上具体处理的逻辑是被代理对象中的处理
动态代理机制:
有2种实现方式:
使用JDK的动态代理:要求必须有对应的接口
使用 CGLib的动态代理:可以没有对应的接口。
使用Cglib创建代理的效率略低于JDK动态代理
JDK反射包中的相关接口和工厂类
接口java.lang.reflect.InvocationHandler
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable; }
• proxy - 在其上调用方法的代理实例
• method - 对应于在代理实例上调用的接口方法的 Method 实例
• args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null
1、抽象角色
public interface Image {
void display();
}
2、具体的目标对象---被代理的对象
public class RealImage implements Image {
@Override
public void display() {
System.out.println("Displaying real image ");
}
}
3、定义代理回调,不是代理对象类,没有具体的代理对象类定义
public class MyProxyHandler implements InvocationHandler {
private Object target;
public MyProxyHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// 不管未来调用的是代理类的任何方法,实际上都是执行这个回调
System.out.println("签订演艺合同"); // 限制对目标对象的访问
Object res = method.invoke(target, args);
return res; }
}
Proxy的静态方法newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)生成代理类
– loader - 定义代理类的类加载器
– interfaces - 代理类要实现的接口列表
– h - 指派方法调用的调用处理程序
4、测试调用
public class Test {
public static void main(String[] args) {
Image proxy = (Image) Proxy.newProxyInstance(Image.class.getClassLoader(),new Class[]{Image.class }, new MyProxyHandler(new RealImage()));创建代理对象,注意这个代理对象是由工具类动态生成的,没有对应的代理类定义
proxy.display();
}
}