前面讲了静态代理,现在来总结动态代理,java动态代理有两种,一种是JDK动态代理,一种是cglib动态代理。
JDK动态代理
动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。
和之前那一篇静态代理一样,我们声明一个生产商品的接口,并有一个实现这个接口的实现类。那么,同样的我们在生产商品之前我们需要进行权限校验。
我们就用到了JDK动态代理。需要的时候自动生成代理。
RightAdvice.java 这个类必须实现InvocationHandler 接口
package com.yc.advice;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//这个类是一个切面类,完成的功能是向目标类的目标方法加入功能(增强)
public class RightAdvice implements InvocationHandler {
// 代理模式中一定要有目标类的引用
private Object targetObject; // 注意,这个就是目标类的引用
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String methodName = method.getName();
if (methodName.startsWith("add") || methodName.startsWith("del")
|| methodName.startsWith("update")
|| methodName.startsWith("modity")) {
// 在invoke中加入你要增强的代码
check();// 前置增强
}
// 调用目标的对应的方法
Object returnValue = method.invoke(targetObject);
return returnValue;
}
// 创建一个方法来完成创见代理对象
public Object createInstance(Object targetObject) {
this.targetObject = targetObject;
// 生成一个代理对象
// 生成一个代理对象,这个代理对象是根据目标对象的接口生成的
System.out.println(targetObject.getClass().getClassLoader());
System.out.println(targetObject.getClass().getInterfaces());
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
// 在客户端,我们调用 crateInstance() 得到一个代理的对象的方法 --》 它就会自动加调(this)--》invoke
}
//增强
private void check() {
System.out.println("****************");
System.out.println("权限检查");
System.out.println("****************");
}
}
其中
public Object invoke(Object proxy, Method method, Object[] args)
参数在实际使用时,第一个参数obj代表一般是指代理类,method是指被代理的方法,args为该方法的参数数组,这个抽象方法在动态类中的动态实现。
测试类:
RightAdvice ra=new RightAdvice();
ProductBiz pb=new ProductBizImpl();
ProductBiz pbProxy=(ProductBiz) ra.createInstance(pb);
pbProxy.addProduct();
输出结果:
****************
权限检查
****************
**********************
添加产品
**********************