AOP所使用的代理模式就是动态代理,
动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的
所以在学AOP之前利用JDK动态代理来形象的阐述具体的内容——JDK的动态代理需要了解两个类:
核心 : InvocationHandler 和 Proxy
用一个以Object 所有类的父类作为类类型写一个万能的动态代理:
proxyInvocationHandle:
package demoAop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class proxyInvocationHandle implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生成代理类
public Object getProxy()
{
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy代理类 method代理类的调用处理程序的方法对象
log(method.getName());//核心是反射机制的内容
Object result=method.invoke(target,args);
return result;
}
public void log(String methodName)
{
System.out.println("执行了"+methodName+"方法");
}
}
UserserviceImpl:
package demoAop;
public class UserserviceImpl implements UserService{
public void delete() {
System.out.println("进行删除操作!");
}
}
userservice 接口;
package demoAop;
public interface UserService {
public void delete();
}
Test类:
package demoAop;
public class Test {
public static void main(String[] args) {
UserserviceImpl userserviceimpl=new UserserviceImpl();
//代理实例的调用处理程序
proxyInvocationHandle pih=new proxyInvocationHandle();
pih.setTarget(userserviceimpl);//需要被代理的类的实例
//动态生成代理类
UserService proxy=(UserService)pih.getProxy();
proxy.delete();
}
}
动态代理 jdk动态代理
public interface InvocationHandlerInvocationHandler是由代理实例的调用处理程序实现的接口 。 每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法 invocationHandle本身就是一个调用处理程序。 Object invoke(Object proxy, 方法 method, Object[] args) 处理代理实例上的方法调用并返回结果。
invoke
Object invoke(Object proxy, 方法 method, Object[] args) throws Throwable
处理代理实例上的方法调用并返回结果。 当在与之关联的代理实例上调用方法时,将在调用处理程序中调用此方法。 参数 proxy - 调用该方法的代理实例 method -所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。 args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。 原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。 结果 从代理实例上的方法调用返回的值。 如果接口方法的声明返回类型是原始类型,则此方法返回的值必须是对应的基本包装类的实例; 否则,它必须是可声明返回类型的类型。 如果此方法返回的值是null和接口方法的返回类型是基本类型,那么NullPointerException将由代理实例的方法调用抛出。 如上所述,如果此方法返回的值,否则不会与接口方法的声明的返回类型兼容,一个ClassCastException将代理实例的方法调用将抛出。