java中实现动态代理可以使用jdk提供的proxy实现,也可以通过cglib实现。二者主要的区别在于 proxy只能实代理实现了接口的类。cglib可以动态代理所有的 非final的类的非final方法
利用 jdk 反射机制实现动态代理
核心要点
- 代理类必须实现 InvocationHandler 接口
- 被代理的类必须继承一个接口
测试代码
- 接口类
public interface jdkService {
void hello();
}
- 接口实现类
public class Service implements jdkService {
public Service(String name) {
this.name = name;
}
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public final void print() {
System.out.println(this.name);
}
@Override
public void hello() {
System.out.println("hello method" + this.name);
}
}
- jdk代理类
public class JdkProxy implements InvocationHandler {
/**
* 被代理的类
*/
private Class target;
/**
* 被代理的对象
*/
private Object targetProxy;
public JdkProxy(Class<?> targetClass) {
try {
this.target = targetClass;
} catch (Exception e) {
e.printStackTrace();
}
}
public Object createProxy(String name) {
try {
this.targetProxy = target.getConstructor(new Class[]{String.class}).newInstance(new Object[]{name});
} catch (Exception e) {
e.printStackTrace();
}
return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.target.getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(method.getName());
return method.invoke(targetProxy, args);
}
}
cglib实现动态代理
核心
- 代理类必须实现 MethodInterceptor 接口
- 只能代理非final的方法
cglib实现的代理类
public class CglibProxy implements MethodInterceptor {
private Class<?> target;
public CglibProxy(Class<?> target) {
this.target = target;
}
Object createProxy(String name) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target);
enhancer.setCallback(this);
Object[] args = new String[]{name};
Class[] classes = new Class[]{String.class};
return enhancer.create(classes, args);
}
/**
* 在拦截器这个方法中可以实现aop
* 只是会拦截非final class, 非final的method
* cglib 无法代理final的方法
*
* @param var1 需要代理的对象
* @param var2 被代理的方法
* @param var3 参数
* @param var4 代理方法
* @return
* @throws Throwable
*/
public Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable {
// 对方法进行拦截
System.out.println(var2.getName());
return var4.invokeSuper(var1, var3);
}
}
测试类
public class Reflect {
public static void main(String args[]) {
//cg 动态代理
CglibProxy proxy = new CglibProxy(Service.class);
Service service = (Service) proxy.createProxy("CglibProxy");
service.setName("CglibProxy");
System.out.println(service.getName());
// 不能代理final的方法
service.print();
service.hello();
System.out.println("------jdk");
// jdk 动态代理
Reflect.JdkProxy jdkPorxy = new Reflect.JdkProxy(Service.class);
jdkService service1 = (jdkService) jdkPorxy.createProxy("JdkProxy");
service1.hello();
}
}
网友评论