关于动态代理模式里面有两种实现,一种是jdk实现,一种是cglib来实现。
下面来整jdk来实现动态代理的Java实例。
jdk动态代理模式里面有个拦截器的概念,在jdk中,只要实现了InvocationHandler这个接口的类就是一个拦截器类。
还使用了些反射的相关概念。
拦截器的概念不了解没关系,假如写了个请求到action,经过拦截器,然后才会到action。然后继续有之后的操作。
拦截器就像一个过滤网,一层层的过滤,只要满足一定条件,才能继续向后执行。
拦截器的作用:控制目标对象的目标方法的执行。
拦截器的具体操作步骤:
1.引入类:目标类和一些扩展方法相关的类。
2.赋值:调用构造函数给相关对象赋值
3.合并逻辑处理:在invoke方法中把所有的逻辑结合在一起。最终决定目标方法是否被调用。
下面看具体的代码实例:
目标接口类:
package com.lxk.designPattern.proxy.dynamicProxy.jdkDynamicProxy;
/**
* 目标接口:
* 包含目标方法的声明
*/
public interface TargetInterface {
/**
* 目标方法
*/
void business();
}
package com.lxk.designPattern.proxy.dynamicProxy.jdkDynamicProxy;
/**
* 被代理的类
* 目标对象类
* 实现目标接口.
* 继而实现目标方法。
*/
public class TargetObject implements TargetInterface {
/**
* 目标方法(即目标操作)
*/
@Override
public void business() {
System.out.println("business");
}
}
package com.lxk.designPattern.proxy.dynamicProxy.jdkDynamicProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理-拦截器
*
* Created by lxk on 2016/11/25
*/
public class MyInterceptor implements InvocationHandler {
private Object target;//目标类
public MyInterceptor(Object target) {
this.target = target;
}
/**
* args 目标方法的参数
* method 目标方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("aaaaa");//切面方法a();
//。。。
method.invoke(this.target, args);//调用目标类的目标方法
//。。。
System.out.println("bbbbb");//切面方法f();
return null;
}
}
package com.lxk.designPattern.proxy.dynamicProxy.jdkDynamicProxy;
import java.lang.reflect.Proxy;
public class MainTest {
public static void main(String[] args) {
//目标对象
TargetObject target = new TargetObject();
//拦截器
MyInterceptor myInterceptor = new MyInterceptor(target);
/*
* Proxy.newProxyInstance参数:
* 1、目标类的类加载器
* 2、目标类的所有的接口
* 3、拦截器
*/
//代理对象,调用系统方法自动生成
TargetInterface proxyObj = (TargetInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), myInterceptor);
proxyObj.business();
}
}
了解了一个,那么另一个也就差不多啦。就继续往下看吧。
为什么要使用这个cglib来实现这个动态代理呢?因为spring框架要用。
具体的代码实现如下:
目标对象类:
package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy;
/**
* 被代理的类
* 目标对象类
*/
public class TargetObject {
/**
* 目标方法(即目标操作)
*/
public void business() {
System.out.println("business");
}
}
package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* 动态代理-拦截器
*
* Created by lxk on 2016/11/25
*/
public class MyInterceptor implements MethodInterceptor {
private Object target;//目标类
public MyInterceptor(Object target) {
this.target = target;
}
/**
* 返回代理对象
* 具体实现,暂时先不追究。
*/
public Object createProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setCallback(this);//回调函数 拦截器
//设置代理对象的父类,可以看到代理对象是目标对象的子类。所以这个接口类就可以省略了。
enhancer.setSuperclass(this.target.getClass());
return enhancer.create();
}
/**
* args 目标方法的参数
* method 目标方法
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("aaaaa");//切面方法a();
//。。。
method.invoke(this.target, objects);//调用目标类的目标方法
//。。。
System.out.println("bbbbb");//切面方法f();
return null;
}
}
package com.lxk.designPattern.proxy.dynamicProxy.cglbDynamicProxy;
public class MainTest {
public static void main(String[] args) {
//目标对象
TargetObject target = new TargetObject();
//拦截器
MyInterceptor myInterceptor = new MyInterceptor(target);
//代理对象,调用cglib系统方法自动生成
//注意:代理类是目标类的子类。
TargetObject proxyObj = (TargetObject) myInterceptor.createProxy();
proxyObj.business();
}
}
首先从文件数上来说,cglib比jdk实现的少了个接口类。因为cglib返回的代理对象是目标对象的子类。而jdk产生的代理对象和目标对象都实现了一个公共接口。
动态代理:
动态代理分为两种:
* jdk的动态代理
* 代理对象和目标对象实现了共同的接口
* 拦截器必须实现InvocationHanlder接口
* cglib的动态代理
* 代理对象是目标对象的子类
* 拦截器必须实现MethodInterceptor接口
* hibernate中session.load采用的是cglib实现的