代理对象相当于现实生活中的房产中介,被代理对象
相当于 房东
避免外界直接修改被代理对象,破坏掉被代理对象原本的功能。
将对被代理对象功能的增强放在代理对象中,
代理对象中存在一个对被代理对象的引用,在使用被代理对象之前或者之后,代理对象可以做一些额外的添油加醋方法。
(这符合开闭原则: 对修改关闭,对拓展开放)
被代理对象 ProxyObjected.java
package src.com.liu.proxy;
//被代理对象(房东)
public class ProxyObjected {
public void process(){
System.out.println("我是被代理对象的方法 process");
}
}
代理对象 ProxyObject.java
package src.com.liu.proxy;
//代理对象(中介)
public class ProxyObject {
private ProxyObjected obj;
ProxyObject(ProxyObjected obj){
this.obj = obj;
}
public void process(){
ProxyObjected obj = this.obj;
System.out.println("====被代理对象的方法执行之前,执行添油加醋的动作");
//执行被代理对象
obj.process();
System.out.println("====被代理对象的方法执行之后,执行一些添油加醋的动作");
}
}
测试代码
package src.com.liu.proxy;
public class Test {
public static void main(String[] args) {
//创建被代理对象
ProxyObjected obj = new ProxyObjected();
//创建代理对象(把被代理对象当作参数传入)
ProxyObject proxyObject = new ProxyObject(obj);
//执行代理对象的方法(先执行添油加醋,再执行被代理对象的process,再执行添油加醋)
proxyObject.process();
}
}
动态代理的意思是我们不直接生成我们的proxyObject,
而是提供 1.被代理对象和 2.增强方法(那些添油加醋方法)3.以及各自调用时机,然后在代码运行时自动帮我们生成一个proxyObject。
好处: 将代理对象方法和增强方法(添油加醋方法)解耦分离,使代码更具拓展型和可维护性。
这里只讲jdk动态代理
2.1 被代理对象 TestDao.java
package src.com.liu.proxy.dynamic.jdk;
public interface TestDao {
public void save();
public void modify();
public void delete();
}
2.2 被代理对象实现类 TestDaoImpl.java
package src.com.liu.proxy.dynamic.jdk;
public class TestDaoImpl implements TestDao{
@Override
public void save() {
System.out.println("保存");
}
@Override
public void modify() {
System.out.println("修改");
}
@Override
public void delete() {
System.out.println("删除");
}
}
2.3 代理对象的增强方法 类 Enhancement.java
package src.com.liu.proxy.dynamic.jdk;
//代理对象的增强方法 类
public class Enhancement {
public void check(){
System.out.println("模拟权限控制");
}
public void except(){
System.out.println("模拟异常处理");
}
public void log(){
System.out.println("模拟日志记录");
}
public void monitor(){
System.out.println("性能监测");
}
}
2.4 代理对象类 JDKDynamicProxy.java
package src.com.liu.proxy.dynamic.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//代理对象类
public class JDKDynamicProxy implements InvocationHandler
{
private TestDao testDao;//被代理对象
JDKDynamicProxy(TestDao dao){
this.testDao= dao;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Enhancement enhancement = new Enhancement();
enhancement.check();
enhancement.except();
//调用被代理对象方法
Object obj = method.invoke(testDao,args);
enhancement.log();
enhancement.monitor();
return obj;
}
}
2.5 JDKDynamicTest.java
package src.com.liu.proxy.dynamic.jdk;
import java.lang.reflect.Proxy;
public class JDKDynamicTest {
public static void main(String[] args) {
//创建被代理对象
TestDao testDao = new TestDaoImpl();
//创建代理对象,并将被代理对象注入到代理对象中
JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy(testDao);
//得到一个类加载器
ClassLoader classLoader = JDKDynamicProxy.class.getClassLoader();
//得到被代理对象的所有接口
Class[] clazz = testDao.getClass().getInterfaces();
//生成代理对象
TestDao testDaoAdvice = (TestDao) Proxy.newProxyInstance(classLoader,clazz,jdkDynamicProxy);
//执行方法
testDaoAdvice.save();
System.out.println("====================");
testDaoAdvice.modify();
System.out.println("====================");
testDaoAdvice.delete();
}
}
2.6效果:
2.7 改变 Enhancement.java类中增强方法里的内容时,不改变现有代码运行
运行结果:
这实现了 代理对象里那些添油加醋增强方法 的结偶,
当这些增强方法需要修改时,不用动代理对象类里的代码