首页 > 技术文章 > 学习笔记-Java代理模式

zhucj-java 2019-09-10 10:17 原文

1.代理模式分类

  代理模式在java开发中使用十分普遍,大量运用框架底层,如spring架构、Dubbo等。

  代理模式中三种主要角色

  抽象角色(Subject):

  代理角色(ProxySubject):

  被代理角色(RealSubject)

 

 (1)静态代理 

 

  public interface Subject {

    /**
* #####目的 定义功能接口,提供给真实主题角色和抽象主题角色继承 ####
*/
void request();
}

public class ProxySubject implements Subject {
private RealSubject realSubject;

@Override
public void request() {
System.out.println("=>开启代理访问模式");
if (realSubject == null){
realSubject = new RealSubject();
}
realSubject.request();
System.out.println("=>代理过程完成");
}
}
public class RealSubject implements Subject{
 @Override
public void request() {
System.out.println("访问google搜索");
 }
}

public class ProxyTest {
public static void main(String[] args){
        Subject subject = new ProxySubject();
subject.request();
}
}

--------------------------
运行结果

=>开启代理访问模式
访问google搜索
=>代理过程完成

-------------------------------------------------

2.动态代理

动态代理常用的有JDK动态代理和CGLIB动态代理

下面仅介绍CGLIB动态代理实现过程

public class CGlibProxy implements MethodInterceptor {


private Object object;


/**
* 设置被代理的类
* @param object
* @return
*/
public Object crateProxy(Object object){
this.object = object;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.object.getClass());
enhancer.setCallback(this);
return enhancer.create();
}


/**
* 获取被代理类参数信息
* @param o 被代理对象
* @param method 被代理方法
* @param objects 被代理方法的参数 数组
* @param methodProxy 被代理的方法的proxy对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("=>代理任务开启之前");
//执行被代理方法
String o1 =(String) methodProxy.invokeSuper(o, objects);
System.out.println("=>代理任务结束之后");
//最后返回被代理对象方法返回值o1
return o1;
}

 /***
* ###技术总结#####
* 1.CGLIB代理模式程序运行时发生,将代理类生成字节码,加载被代理类的Classloader中
* 2.使用前需要导入 cglib-nodep jar包
* 3.继承代理类继承MethodInterceptor 实现intercept接口 实现方法调用前和调用之后数据处理
* 4.methodProxy.invokeSuper() 实现代被代理类方法
* 5.还需定义一个创建被代理类对象的方法createProxy(),使用Enhancer 托管被代理对象
* 6.使用时,只需要创建一个代理对象,调用createProxy()方法,传入需被代理对象,返回被代理对象实例
* 7.通过实例去调用自己方法,继而实现对方法/参数/返回值代理功能
*/
}

public class ProxyTest {

public static void main(String[] args){
CGlibProxy cGlibProxy = new CGlibProxy();
RealSubject o =(RealSubject) cGlibProxy.crateProxy(new RealSubject());
o.request();
}
}

运行结果
-------------------

=>代理任务开启之前
访问google搜索
=>代理任务结束之后

------------------------------------

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.1</version>
</dependency>
 

推荐阅读