代理设计模式
使用一个代理对象将对象包装起来,使用该代理对象取代原始对象。
任何对原始对象的调用都要通过代理,该代理对象决定是否以及何时将方法调用赚到原始对象上。
动态代理可以在程序运行时根据需要动态创建目标类的代理对象,
静态代理
特点:代理类和被代理类在编译期间就已经确定。
import java.io.*;
//静态代理举例
interface ClothFactory{
void produceCloth();
}
//代理类
class ProxyClothFactory implements ClothFactory{
private ClothFactory factory; //就用被代理类对象进行实例化
public ProxyClothFactory(ClothFactory factory) {
this.factory = factory;
}
@Override
public void produceCloth() {
System.out.println("准备工作。。。");
factory.produceCloth();
System.out.println("后续收尾工作。。。");
}
}
//被代理类
class NikeCLothFactory implements ClothFactory{
@Override
public void produceCloth() {
System.out.println("耐克工厂生产运动服");
}
}
public class test {
public static void main(String[] args) throws Exception {
//创建被代理对象
NikeCLothFactory nike = new NikeCLothFactory();
//创建代理对象
ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nike);
proxyClothFactory.produceCloth();
}
}
动态代理
- 需求一:根据加载到内存中的被代理类,动态创建一个代理类及其对象。
- 当通过代理类的对象调用方法时,需要动态调用被代理类的同名方法。
代码
interface Human{
String getBelief();
void eat(String food);
}
//被代理类
class SuperMan implements Human{
@Override
public String getBelief() {
return "I can fly";
}
@Override
public void eat(String food) {
System.out.println("超人喜欢吃"+food);
}
}
//动态代理
class ProxyFactory{
//调用此方法返回一个代理类对象
public static Object GetProxyInstance(Object obj){ //obj为被代理类的对象
MyInvocationHandler hander = new MyInvocationHandler();
//传入被代理对象
hander.bind(obj);
//参数:获取类加载器;获取接口;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),hander);
}
}
//主要代理如何实现方法
class MyInvocationHandler implements InvocationHandler{
//当直接用反射时 invoke表示调用类中的方法
//当通过代理类的对象调用方法时,就会自动调用如下方法
//将被代理类要执行的方法的功能声明在invoke中
//被代理类 赋值时 需要使用被代理类对象
private Object obj;
public void bind(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法
//obj:被代理类的对象
Object returnValue = method.invoke(obj,args);
return returnValue;
}
}
public class test {
public static void main(String[] args) throws Exception {
SuperMan superMan = new SuperMan();
//不能写成superMan 因为它是被代理类 不是代理类
//proxyInstance为代理类
Human proxyInstance = (Human)ProxyFactory.GetProxyInstance(superMan);
//代理操作代理类
proxyInstance.getBelief();
//当通过代理类对象调用方法时,会自动调用被代理类中同名的方法
proxyInstance.eat("麻花");
}
}
静态代理改为动态代理
interface ClothFactory{
void produceCloth();
}
//被代理类
class NikeCLothFactory implements ClothFactory{
@Override
public void produceCloth() {
System.out.println("耐克工厂生产运动服");
}
}
//动态代理
class ProxyFactory{
//调用此方法返回一个代理类对象
public static Object GetProxyInstance(Object obj){ //obj为被代理类的对象
MyInvocationHandler hander = new MyInvocationHandler();
//传入被代理对象
hander.bind(obj);
//参数:获取类加载器;获取接口;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),hander);
}
}
//主要代理如何实现方法
class MyInvocationHandler implements InvocationHandler{
private Object obj;
public void bind(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法
//obj:被代理类的对象
Object returnValue = method.invoke(obj,args);
return returnValue;
}
}
public class test {
public static void main(String[] args) throws Exception {
NikeCLothFactory nikeCLothFactory = new NikeCLothFactory();
ClothFactory proxyInstance = (ClothFactory) ProxyFactory.GetProxyInstance(nikeCLothFactory);
proxyInstance.produceCloth();
}
}