JDK动态代理
示例(一个简单的动态代理)
package com.lnjecit.proxy.dynamic.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDKDynamicProxy
* jdkd动态代理
*
* @author
* @create 2018-03-29 16:17
**/
public class JDKDynamicProxy implements InvocationHandler {
private Object target;
public JDKDynamicProxy(Object target) {
this.target = target;
}
/**
* 获取被代理接口实例对象
* @param <T>
* @return
*/
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Do something before");
Object result = method.invoke(target, args);
System.out.println("Do something after");
return result;
}
}
cglib动态代理
和JDK动态代理的比较
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
示例
所有方法使用同一个代理
1)目标类
public class Dao {
public void update() {
System.out.println("PeopleDao.update()");
}
public void select() {
System.out.println("PeopleDao.select()");
}
}
2)回调类
public class DaoProxy implements MethodInterceptor {
@Override
public Object intercept(Object object, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
System.out.println("Before Method Invoke");
proxy.invokeSuper(object, objects);
System.out.println("After Method Invoke");
return object;
}
}
3)生成和使用代理类
public class CglibTest {
@Test
public void testCglib() {
DaoProxy daoProxy = new DaoProxy();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Dao.class);
enhancer.setCallback(daoProxy);
Dao dao = (Dao)enhancer.create();
dao.update();
dao.select();
}
}
不同方法定义不同回调
在CGLib回调时可以设置对不同方法执行不同的回调逻辑,或者根本不执行回调。
1)回调类
public class DaoAnotherProxy implements MethodInterceptor {
@Override
public Object intercept(Object object, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
System.out.println("StartTime=[" + System.currentTimeMillis() + "]");
method.invoke(object, objects);
System.out.println("EndTime=[" + System.currentTimeMillis() + "]");
return object;
}
}
2)回调过滤器
public class DaoFilter implements CallbackFilter {
@Override
public int accept(Method method) {
if ("select".equals(method.getName())) {
return 0;
}
return 1;
}
}
其中return值为被代理类的各个方法在回调数组Callback[]中的位置索引。
3)生成代理类
public class CglibTest {
@Test
public void testCglib() {
DaoProxy daoProxy = new DaoProxy();
DaoAnotherProxy daoAnotherProxy = new DaoAnotherProxy();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Dao.class);
enhancer.setCallbacks(new Callback[] {daoProxy, daoAnotherProxy, NoOp.INSTANCE});
enhancer.setCallbackFilter(new DaoFilter());
Dao dao = (Dao)enhancer.create();
dao.update();
dao.select();
}
}
补充:NoOp.INSTANCE表示什么也不做