设计模式-代理模式
本文仅对设计模式学习的查缺补漏
静态代理
例子
/**
* 静态代理举例
*
* 特点:代理类和被代理类在编译期间,就确定下来了
*
* @Author: fxx
* @Date: 2020/12/30 15:04
*/
interface ClothFactory{
public void produceClothes();
}
/**
* 被代理类
*/
class NikeClothFactory implements ClothFactory{
@Override
public void produceClothes() {
System.out.println("Nike制鞋");
}
}
/**
* 代理类
*/
class ProxyClothFactory implements ClothFactory{
private ClothFactory factory;
public ProxyClothFactory(){}
public ProxyClothFactory(ClothFactory factory){
this.factory = factory;
}
@Override
public void produceClothes() {
System.out.println("代理工厂接单");
factory.produceClothes();
System.out.println("代理工厂收钱");
}
}
public class StaticProxyTest {
public static void main(String[] args){
ClothFactory nikeClothFactory = new NikeClothFactory();
ClothFactory proxyClothFactory = new ProxyClothFactory(nikeClothFactory);
proxyClothFactory.produceClothes();
}
}
结果
动态代理
要想实现动态代理,需要解决什么问题?
- 问题一:如何根据加载到内存中的被代理类,动态地创建一个代理类及其对象。
- 问题二:当通过代理类的对象调用方法时,如何动态地去调用被代理类中的同名方法。
例子
/**
* 动态代理
*
* @Author: fxx
* @Date: 2020/12/30 15:19
*/
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 getInstance(Object obj){ //obj:被代理类对象
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
myInvocationHandler.bind(obj); //传入被代理类
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), myInvocationHandler);
}
}
class MyInvocationHandler implements InvocationHandler{
private Object obj; //需要使用被代理类的对象进行赋值
public void bind(Object obj){
this.obj = obj;
}
//当我们通过代理类的对象,调用方法a时,就会自动下面这个invoke方法
//将被代理类要执行的方法a的功能就声明在下面这个invoke()方法中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
proxy:代理类对象
method:代理类调用的方法,也是被代理类的同名方法,即被代理类要调用的方法
args:代理类调用方法时传入的参数
*/
//method.invoke()的返回值即为被代理类调用方法的返回值
return method.invoke(obj, args);
}
}
public class ProxyTest {
public static void main(String[] args){
SuperMan superMan = new SuperMan(); //被代理类的对象
Human instance = (Human) ProxyFactory.getInstance(superMan); //生成一个代理类
//代理类调用方法,其实是被代理类执行
String str = instance.getBelief();
System.out.println(str);
instance.eat("火锅");
NikeClothFactory nikeClothFactory = new NikeClothFactory();
ClothFactory instance1 = (ClothFactory) ProxyFactory.getInstance(nikeClothFactory);
instance1.produceClothes();
}
}