1. JDK
Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface的实例。
JDK动态代理必须提供接口才可代理
public interface HelloService {
void sayHello1(String name);
String sayHello2(String name);
}
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello1(String name) {
System.out.println("hello1 " + name);
}
@Override
public String sayHello2(String name) {
System.out.println("hello2 " + name);
return name;
}
}
代理对象实现 InvocationHandler 方法,直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个接口对象。
public class JdkProxy implements InvocationHandler {
// 被代理对象
private Object target = null;
/**
* 创建代理对象
* @param target
* @return
*/
public Object bind(Object target) {
this.target = target;
// 参数为:target 类加载器;target 的方法;实现 InvocationHandler 接口的逻辑代理类,即当前类
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 代理对象调用方法
* @param proxy 代理对象
* @param method 方法
* @param args 方法参数
* @return 代理调用方法结果
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理前");
// 调用方法,参数是target不是proxy,因为target中才有具体的方法实现,proxy中没有
Object obj = method.invoke(target,args);
System.out.println("代理后");
return obj;
}
}
JDK动态代理测试:
@Test
public void jdkProxyTest(){
JdkProxy jdkProxy = new JdkProxy();
// 创建代理对象
HelloService proxy = (HelloService)jdkProxy.bind(new HelloServiceImpl());
// 调用方法
proxy.sayHello1("jdk1");
String sayHello2Return = proxy.sayHello2("jdk2");
System.out.println("sayHello2Return " + sayHello2Return);
}
测试结果:
代理前
hello1 jdk1
代理后
代理前
hello2 jdk2
代理后
sayHello2Return jdk2
2. CGLIB
CGLIB动态代理只需要非抽象类即可代理
public class HelloServiceImpl {
public void sayHello1(String name) {
System.out.println("hello1 " + name);
}
public String sayHello2(String name) {
System.out.println("hello2 " + name);
return name;
}
}
代理对象实现 MethodInterceptor 接口
public class CglibProxy implements MethodInterceptor {
/**
* 生成cglib代理对象
* @param cls
* @return
*/
public Object getProxy(Class cls){
// cglib 增强类对象
Enhancer enhancer = new Enhancer();
// 设置增强类型
enhancer.setSuperclass(cls);
// 定义代理逻辑对象,即实现 MethodInterceptor 接口的对象
enhancer.setCallback(this);
return enhancer.create();
}
/**
* 代理逻辑方法
* @param o 代理对象
* @param method 方法
* @param objects 方法参数
* @param methodProxy 方法代理
* @return 代理逻辑返回
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("代理前");
Object returnObj = methodProxy.invokeSuper(o, objects);
System.out.println("代理后");
return returnObj;
}
}
CGLIB动态代理测试:
@Test
public void cglibProxyTest(){
CglibProxy cglibProxy = new CglibProxy();
HelloServiceImpl helloServiceImpl = (HelloServiceImpl) cglibProxy.getProxy(HelloServiceImpl.class);
helloServiceImpl.sayHello1("cglib");
String returnObj = helloServiceImpl.sayHello2("cglib");
System.out.println(returnObj);
}
测试结果:
代理前
hello1 cglib
代理后
代理前
hello2 cglib
代理后
cglib