在上一篇博客中简单写了一下静态代理,这里主要讲一下动态代理
动态代理主要有两种
JDK动态代理 CGLIB动态代理
那这两种代理有什么区别呢?
(根据自己的理解总结)
1.JDK动态代理
他的特点是:目标对象必须有接口
他的实质是:创建了接口的一个实现类
他运行的时机:程序运行时
2.CGLIB动态代理
他的特点是:在一个类型没有接口的情况下进行代理
他的实质是:在内存中构建目标类型的子类
他运行的时机是:编译时
简单介绍完这两种代理后,就用个例子具体看怎么实现动态代理
先做JDK动态代理
准备一个接口ISomeService,接口中有一个方法doSome(),和一个这个接口的实现类SomeServiceImpl,并重写其中的方法,具体代码如下
package demo15;
/**
* Created by mycom on 2018/3/8.
*/
public interface ISomeService
{
public void doSome();
}
package demo15;
/**
* Created by mycom on 2018/3/8.
*/
public class SomeServiceImpl implements ISomeService {
public void doSome() {
System.out.println("十点十分的复习");
}
}
使用JDK动态代理不需要再配置文件中进行配置,所以现在直接进行测试,但是测试的时候不能使用单测,而是使用main方法进行测试
package demo15;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Created by mycom on 2018/3/8.
*/
public class Test {
public static void main(String[] args) {
//首先创建一个接口的实现类
final SomeServiceImpl service=new SomeServiceImpl();
//在调用方法之前想使用动态代理记录一下日志,生成动态代理,返回的是接口
ISomeService proxyInstance =(ISomeService) Proxy.newProxyInstance(service.getClass().getClassLoader(),
service.getClass().getInterfaces(), new InvocationHandler() {
/**
*
* @param proxy 代理对象
* @param method 目标类型的方法
* @param args 方法的参数
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//在这里记录一下日志
System.out.println("before=====");
//调用method 的
method.invoke(service,args);//相当于执行目标类型的方法
System.out.println("after=======");
return null;
}
});
//调用动态代理中的方法中的方法
proxyInstance.doSome();
}
}
运行的结果如下

这说明运行时先执行了invoke方法,再执行接口中doSome的方法,实验成功!
使用CGLIB动态代理实现上述中的运行结果,如何实现呢?
这时就不用再创建接口了,(在这里我就使用上面的SomeServiceImpl这个类了,这个类中不用做改动),我直接进行测试了,测试还和上面一样,使用main方法测试,不用配置文件
package demo09;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* Created by mycom on 2018/3/8.
*/
public class Test {
public static void main(String[] args) {
final SomeServiceImpl service=new SomeServiceImpl();
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(service.getClass());
enhancer.setCallback(new MethodInterceptor() {
/**
*
* @param o 代理对象
* @param method 目标类型的方法
* @param objects 目标方法的参数
* @param methodProxy 代理类的方法 是一个新的参数
* @return
* @throws Throwable
*/
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before=====");
methodProxy.invoke(service,objects);
System.out.println("after=====");
return null;
}
});
SomeServiceImpl proxy =(SomeServiceImpl) enhancer.create();
proxy.doSome();
}
}
运行结果和上面的一样,这就是两种方法实现动态代理!
