代理模式
【摘要】
概念:委托一个代理类对另一个类进行控制(代理类中有被代理类的对象,同时可以在代理类中增强)
使用场景:aop(可以控制被代理类是否被调用,是否被代理)。
优点:1.确保被代理类的隐秘性
2.降低耦合性(不用挨个加需要增强的方法)
缺点:类数量的增多...
概念:委托一个代理类对另一个类进行控制(代理类中有被代理类的对象,同时可以在代理类中增强)
使用场景:aop(可以控制被代理类是否被调用,是否被代理)。
优点:1.确保被代理类的隐秘性
2.降低耦合性(不用挨个加需要增强的方法)
缺点:类数量的增多,结构更复杂。
类图:
代码:
静态代理
1 静态代理:静态代理就是把增强的方法写在代理的类中,在编译时就确定了,这样耦合性比较高,除了方法量级较小或者增强的方法固定,其他情况不推荐。
subject接口
-
public interface PlayLol{
-
public void plya();
-
}
realSubject
-
public class IsPlay implements PlayLol{
-
public void play() {
-
System.out.println("开始玩");
-
}
-
}
proxy
-
public class ProxySubject implements PlayLol{
-
-
private PlayLol playLol;
-
//关键,将被代理对象传进来
-
public ProxySubject(final PlayLol playLol) {
-
this.playLol = playLol;
-
}
-
-
public void play() {
-
System.out.println("打开电脑");
-
//可以增加控制 ,可以不让他玩。。。
-
subject.play();
-
System.out.println("15投");
-
}
-
}
调用
-
public class MainClass {
-
public static void main(String[] args) {
-
PlayLol playLol = new IsPlay();
-
playLol.paly();
-
-
System.out.println("============");
-
-
ProxySubject proxySubject = new ProxySubject(playLol);
-
proxySubject.paly();
-
}
-
}
2.动态代理:
JDK代理
代理类
-
public class ProxyHandler implements InvocationHandler {
-
-
private Object object;
-
-
public DynamicProxyHandler(final Object object) {
-
this.object = object;
-
}
-
-
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-
System.out.println("先开电脑");
-
Object result = method.invoke(object, args);
-
System.out.println("关电脑");
-
return result;
-
}
-
}
调用:
-
public class MainClass {
-
public static void main(String[] args) {
-
PlayLol subject = new IsPlay();
-
/**
-
* ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
-
* Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
-
* InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法
-
* 都是固定写法
-
*/
-
PlayLol proxySubject = (PlayLol) Proxy.newProxyInstance(PlayLol.class.getClassLoader(),
-
new Class[]{PlayLol.class},
-
new ProxyHandler(subject));
-
proxySubject.play();
-
}
CGLib动态代理
如果被代理类没有接口不可以使用jdk动态代理
代码:
被代理类
-
public class IsPlay{
-
public void play() {
-
System.out.println("开始玩");
-
}
-
}
代理类
-
public class CglibProxy implements MethodInterceptor {
-
private Object target;//业务类对象,供代理方法中进行真正的业务方法调用
-
-
//相当于JDK动态代理中的绑定
-
public Object getInstance(Object target) {
-
this.target = target; //给业务对象赋值
-
Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
-
enhancer.setSuperclass(this.target.getClass()); //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
-
//设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
-
enhancer.setCallback(this);
-
// 创建动态代理类对象并返回
-
return enhancer.create();
-
// 以上都是固定写反
-
}
-
// 实现回调方法
-
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
-
System.out.println("开电脑");
-
proxy.invokeSuper(obj, args); //调用业务类(父类中)的方法
-
System.out.println("关电脑");
-
return null;
-
}
-
}
调用
-
public class MainClass {
-
public static void main(String[] args) {
-
IsPlay play= new IsPlay();
-
CglibProxy cglibProxy = new CglibProxy();
-
IsPlay realSubjectProxy =
-
(IsPlay) cglibProxy.getInstance(play);
-
realSubjectProxy.play();
-
}
-
}
引用:CGLIB创建的动态代理对象比JDK创建的动态代理对象的性能更高,但是CGLIB创建代理对象时所花费的时间却比JDK多得多。所以对于单例的对象,因为无需频繁创建对象,用CGLIB合适,反之使用JDK方式要更为合适一些。同时由于CGLib由于是采用动态创建子类的方法,对于final修饰的方法无法进行代理。
文章来源: baocl.blog.csdn.net,作者:小黄鸡1992,版权归原作者所有,如需转载,请联系作者。
原文链接:baocl.blog.csdn.net/article/details/102546365
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)