动态代理
代理
代理就是被代理对象没有能力或不想去做某些事 因此需要借助第三方类来完成这些事 就叫做代理。
Java中为什么需要代理
场景1 统计每个方法运行时消耗的时间
在没有代理的情况下 所有方法都要手动添加监测耗时的代码 这样就会出现大量的冗余代码。
使用动态代理就可以很好的避免这种冗余代码出现
动态代理
动态代理指的是代理对象是在程序运行过程中动态创建的 因此被称为动态代理。
入门案例
userService接口 该接口实现llogin,delete等方法
String login(String loginName,String password);
void deleteAll();
userServiceImpl 实现类
public class UserServiceImpl implements UserService {
@Override
public String login(String loginName, String password) {
String rs = "用户名或密码错误";
if ("admin".equals(loginName) && "123456".equals(password)) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
rs = "登录成功";
}
return rs;
}
@Override
public void deleteAll() {
System.out.println("删除成功");
}
}
proxyUtil 动态代理工具类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
代理工具类
给每个接口添加动态代理
其中 java.lang.reflect.Proxy 是Java的动态代理类 提供了一个静态方法 为一组接口实现动态代理类及对象
public static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
参数1 类加载器
参数2 被代理对象的全部实现的接口 以便代理对象可以知道为哪些方法做代理 - 为接口的所有方法做代理
参数3 代理真正的执行方法,也就是代理对象的处理逻辑
*/
public class ProxyUtil {
public static <T> T getProxy(Object obj){
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
/*
newProxyInstance参数解释
proxy 业务代理对象本身
method 代表当前正在被代理执行的方法
args 代表执行代理的方法时需要的参数
例如 执行login(userName,password)
method = login
args = [userName,password]
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long sTime = System.currentTimeMillis();
// 触发被代理对象中要执行的方法
Object rs = method.invoke(obj,args);
long eTime = System.currentTimeMillis();
System.out.println(method.getName()+"方法耗时:"+(eTime - sTime)/1000.0+" s");
return rs;
}
});
}
}
测试
public class Test {
public static void main(String[] args) {
UserService service = ProxyUtil.getProxy(new UserServiceImpl());
service.login("admin","123456");
service.deleteAll();
}
}