原文链接:设计模式——动态代理
2021-07-04 23:30 晚 🐟
动态代理:对静态代理的升级,解决静态代理
1、同时代理多个类,会造成类的无限扩张
2、多个重复的代理,在方法中重复出现。
**注意:**代理的对interface类
应用场景:
1、原有代码不可更改,不原有方法的增强
2、mybatis的日志模块,spring源码多个模块涉及
public interface People {
/**
* 睡觉行为
*/
void sleep();
/**
* 吃饭行为
*/
void eat();
}
public class User implements People {
@Override
public void sleep() {
System.out.println("user在睡觉");
}
@Override
public void eat() {
System.out.println("user吃饭");
}
}
// 对people接口整个进行增强
public class ProxyPeople implements InvocationHandler {
/**
* 需要被代理的接口
*/
private final People people;
public ProxyPeople(People people) {
this.people = people;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// 对object继承的方法忽略
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
// 对方法进行增强
if ("sleep".equals(method.getName())) {
System.out.println("我是动态代理:睡前洗脸");
return method.invoke(people, args);
} else if ("eat".equals(method.getName())) {
// 调用原方法
//method.invoke(people, args);
System.out.println("我是动态代理:吃完饭喝水");
// 前置增强
return method.invoke(people, args);
} else {
return method.invoke(people, args);
}
} catch (Throwable t) {
throw new Exception("t:" + t.getMessage());
}
}
// 创建增强代理对象
public static People newInstance(People people) {
InvocationHandler handler = new ProxyUser(people);
ClassLoader cl = People.class.getClassLoader();
//return (People) Proxy.newProxyInstance(cl, people.getClass().getInterfaces(), handler);
return (People) Proxy.newProxyInstance(cl, new Class[]{People.class}, handler);
}
}
public class ProxyTest {
@Test
public void test() {
People userProxy = ProxyUser.newInstance(new User());
userProxy.eat();
userProxy.sleep();
}
}
// 输出结果
user吃饭
我是动态代理:吃完饭喝水
user在睡觉
我是动态代理:睡前洗脸
// ** 当people无限扩张时,所有重写其方法的类都具有,增强方法**