代理模式
给某一个对象提供一个代理,并由代理对象控制对原对象的引用
代理模式设计类图如下:
代理模式包含如下角色:
- Subject: 抽象主题角色
- Proxy: 代理主题角色
- RealSubject: 真实主题角色
代理类实现代码:
public class Proxy implements Subject {
private RealSubject realSubject = new RealSubject();
public void preRequest()
{…...}
public void request()
{
preRequest();
realSubject.request();
postRequest();
}
public void postRequest()
{……}
}
java动态代理
动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问。同时可以在访问真实对象前后添加一些操作。
代理分为两个步骤
- 代理对象和真实对象建立关系
- 实现代理对象的逻辑方法
动态代理技术
java中常见有一下两种代理
- JDK动态代理
- CGLIB动态代理
JDK动态代理
public class JdkProxyExample implements InvocationHandler{
//真实对象
private Object target = null;
/**
*
* 建立代理对象和真实对象的代理关系,并返回代理对象
* @param target
* @return
*/
public Object bind(Object target) {
this.target = target;
//第一个为类加载器,第二个是动态代理对象挂在哪些接口下,第三个是定义实现方法的逻辑代理类
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* proxy: 代理对象
* method: 当前调度方法
* args : 当前调度方法的参数
*/
@Override
public Object invoke(Object proxy,Method method, Object[] args) throws Throwable{
System.out.println("进入代理逻辑方法");
preRequest();
//使用反射机制调用真实对象的方法
Object obj = method.invoke(target, args);
postRequest();
//返回处理结果
return obj;
}
public void preRequest()
{
System.out.println("调用真实对象前的处理...");
}
public void postRequest()
{
System.out.println("调用真实对象后的处理...");
}
public static void main(String args[]) {
JdkProxyExample jdk = new JdkProxyExample();
//建立代理对象和真实对象的代理关系
HelloWorld proxy = (HelloWorld) jdk.bind(new HelloWorldImpl());
//通过代理对象调用真实对象
proxy.sayHelloWorld();
}
}
CGLiB动态代理
JDK动态代理必须提供接口才能使用,而CGLIB(第三方技术)不用
public class CglibProxyExample implements MethodInterceptor{
/**
* 生产CGLIb代理对象
* @param cls Class类
* @return 代理对象
*/
public Object getProxy(Class cls) {
//CGLIB enhancer增强类对象
Enchancer enhancer = new Enhancer();
//设置增强类型
enhancer.setSuperclass(cls);
//定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
enhancer.setCallback(this);
//生成并返回代理对象
return enhancer.create();
}
public Object intercept(Object proxy,Method method, Object[] args, Method methodProxy)throws Throwable{
System.out.println("进入代理逻辑方法");
preRequest();
OBject result = methodProxy.invokeSuper(proxy,args);
postRequest();
return result;
}
}