JAVA 中的动态代理
动态代理和静态代理类的区别在于,动态代理可以在程序运行时,动态地创建代理类,执行被代理类方法的同时,可以运行被代理类调用的拓展方法
JDK 实现的动态代理
JDK 的动态代理要通过import java.lang.reflect
包中的内容实现,代理类需要调用该包下的Proxy
类下的newProxyInstance
方法,返回一个Object
类型的对象,这个对象就是实现代理类功能的对象,通过强制转换,可以转换为被代理类的对象使用
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
上边是newProxyInstance
方法的定义,该方法中有三个参数,第一个ClassLoader
类型是一个类加载器,这个参数是要加载当前的代理类,即假如代理类名为userServiceProxy
,这里的参数即为userServiceProxy.class.getClassLoader()
,第二个则是一个接口,用来表示包含被代理类全部内容的接口
最后一个参数是一个InvocationHandler
的接口,它内部只有一个invoke
方法,用来实现代理类中向被代理类拓展内容的功能,InvocationHandler
类定义如下
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
所以我们实现的InvocationHandler
接口也需要重写这个方法,这个方法也是我们关联代理类和被代理类的关键,该方法需要返回一个Object
类型的对象,我们通过反射,让被代理类和代理类产生关联,并且在这方法中,我们可以自行在其中定义拓展内容
代码
接口、实现类(被代理类)、切面方法类同之前静态代理的没有区别,地址戳:静态代理
代理类
package jdkProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理类
*/
public class UserServiceProxy {
public static UserService createUserService() {
UserService userService = new UserServiceImpl();
MyAspcet aspcet = new MyAspcet();
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(
UserServiceProxy.class.getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
aspcet.before();
Object retObj = method.invoke(userService, args);
System.out.println("拦截到的返回值" + retObj);
aspcet.after();
return retObj;
}
});
return userServiceProxy;
}
}
测试类
package jdkProxy;
/**
* 测试类
*/
public class test {
public static void main(String[] args) {
UserService userService = UserServiceProxy.createUserService();
userService.add();
userService.delete();
}
}
结果
before method
service add
拦截到的返回值null
after method
before method
service delete
拦截到的返回值null
after method