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>