代理模式(Proxy)----Java设计模式
代理模式,见文思义,即对一个类的对象进行代理,对其进行的行为进行检查扩充。
文化起源于生活,代理就是受委托代表当事人进行当事人(这里指对象)应该做的一些活动。
What it is?
什么是代理模式呢?
通俗的讲,为使用此对象的对象提供一种代理以控制扩充对这个对象的使用访问。当一个对象不能直接交给或不适合直接被另一个对象调用时,会使用到代理模式。
代理模式在Java中应用十分广泛,处处都有它的影踪。
常见的代理模式及结构
代理模式在编程思想中十分重要,一般有以下几种代理模式:
1.静态代理
静态代理主要是通过代理对象和被代理对象实现相同的一个父类或接口,通过将被代理对象聚合到代理对象中,在代理对象中也定义相同的行为方法封装扩充原方法,通过调用代理对象中的方法实现执行原对象的方法。
2.动态代理
动态代理实现了对静态方法改进,即代理对象不用继承父类或方法,利用JDK的API,关键在于通过Proxy.newProxyInstance()方法实现动态生成代理对象进行代理。
3.cglib代理
cglib代理实现了对单独对象的代理,不要求对象必须实现一个父类或接口。但是此种代理必须引用cglib包,通过java底层实现代理,在此不在具体阐述,有兴趣的小伙伴可以去b站韩顺平老师的Java设计模式中学习!
4.几种变体代理模式
几种常见的变体代理模式啦,有兴趣的小伙伴们可以自行了解哦~
静态代理实现源码
ITeacherDao(父类)
package com.design_patterns.proxy.staticproxy;
public interface ITeacherDao {
//授课的方法
void teach();
}
TeacherDao(被代理对象)
package com.design_patterns.proxy.staticproxy;
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("老师正在授课中...");
}
}
TeacherDaoProxy(代理对象)
package com.design_patterns.proxy.staticproxy;
//代理对象,静态代理
public class TeacherDaoProxy implements ITeacherDao {
private ITeacherDao iTeacherDao; //定义目标对象,通过接口来进行聚合
public TeacherDaoProxy(ITeacherDao iTeacherDao) {
this.iTeacherDao = iTeacherDao;
}
@Override
public void teach() {
System.out.println("代理开始, 完成某些操作......");
iTeacherDao.teach();
System.out.println("代理结束......");
}
}
Client(客户端)
package com.design_patterns.proxy.staticproxy;
public class Client {
public static void main(String[] args) {
//创建目标对象
TeacherDao teacherDao = new TeacherDao();
//创建代理对象,同时将被代理对象传递给代理对象
TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
//通过代理对象,调用到被代理对象的方法
//即:执行的是代理对象的方法,代理对象再去调用目标对象的方法
teacherDaoProxy.teach();
}
}
动态代理实现源码
ITeacherDao(父类)
package com.design_patterns.proxy.dynamicproxy;
//定义接口
public interface ITeacherDao {
//定义用于教授的方法
void teach();
}
TeacherDao(被代理对象)
package com.design_patterns.proxy.dynamicproxy;
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("老师正在授课中......");
}
}
ProxyFactory(代理工厂)
package com.design_patterns.proxy.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理对象生产工厂
*/
public class ProxyFactory {
//维护一个目标对象,Object
private Object target;
//定义构造方法,对 target 进行初始化
public ProxyFactory(Object target) {
this.target = target;
}
/**
* 1. ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法固定
* 2. Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方法确认类型
* 3. InvocationHandler h: 事情处理,执行目标对象的方法时,会触发事情处理器方法,
* 会把当前执行的目标对象方法作为参数传入
* @return
*/
public Object getProxyInstance(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK代理开始~~~~");
Object invoke = method.invoke(target, args);
System.out.println("JDK代理结束~~~~");
return invoke;
}
});
}
}
Client(客户端)
package com.design_patterns.proxy.dynamicproxy;
//测试类
public class Client {
public static void main(String[] args) {
//创建目标对象
ITeacherDao iTeacherDao = new TeacherDao();
//给目标对象,创建代理对象
ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(iTeacherDao).getProxyInstance();
proxyInstance.teach();
}
}
总结
好啦~完毕!这就是代理模式,小哥讲的可能有些略显粗糙,嘿嘿,但是道理基本上还是这个道理,小伙伴们一定要明白哦,如果有不懂的地方,欢迎在下方留言谈论,小哥看到一定会回复的!