一、 动态代理的快速入门
1 代理的概念
- 就是一个对象,用来对被代理对象的行为做一些辅助工作。
代理的图解
2. 如何创建一个动态代理?
1 必须定义一个接口
2 被代理对象实现这个接口
3 使用Proxy类的方法,为被代理对象返回一个代理对象
核心代码
被代理对象/Star
private String name;
public Star(String name) {
this.name = name;
}
被代理对象的接口/Skills
void dancing(); //善舞
void singing(); //能歌
代理对象/StarAgent
public static Skills getProxy(Star star){
//生产代理对象
//类加载器 对象实现的接口列表 核心处理器
return (Skills) Proxy.newProxyInstance(star.getClass().getClassLoader(),
star.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("=========买门票才能进场看===========");
//method 正在调用的方法对象
Object rs = method.invoke(star, args);
System.out.println("=======收尾款表演结束================");
return rs;
}
});
}
代理对象测试类
@Test
public void test(){
//创建一个对象(杨超越) 类的对象必须具有实现接口
Star star = new Star("杨超越");
/*star.dancing();
star.singing();*/
//为这个类对象创建一个代理对象
Skills starProxy = StarAgent.getProxy(star);
starProxy.singing();
starProxy.dancing();
}
3. 代理的执行流程
二、动态代理的实际应用
- 模拟企业管理业务,包含用户登录、用户删除、用户查询,统计每一个功能的耗时。
使用动态代理的性能分析:
问题:业务对象的每个方法都要进行性能分析,存在大量重复代码。
优点:
1. 在不改变方法源码的情况下,实现对方法功能的增强,提高代码的复用
2. 简化编程工作,提高开发效率,提高软件系统的可扩展性
3. 可以为被代理对象的所有方法做代理
4. 支持任意接口类型的实现类,也可以直接为接口本身做代理
核心代码
用户代理对象/UserAgent
//为任意接口做代理
public static <T> T getProxy(UserService userService){
return (T) Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
//真正触发对象的代理执行
Object rs = method.invoke(userService, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + "方法耗时:" + (endTime - startTime) / 1000.0 + "s");
return rs;
}
});
}
用户业务的接口/UserService
String login(String username, String password);
void deleteUsers();
String selectUsers();
用户业务接口实现类/UserServiceImpl
@Override
public String login(String username, String password) {
String rs = "登录名或密码错误";
if ("admin".equals(username) && "123456".equals(password)){
rs = "登录成功";
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return rs;
}
@Override
public void deleteUsers() {
try {
System.out.println("=========您正在删除数据~~~===========");
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String selectUsers() {
String rs = "正在查询10000条数据";
try {
System.out.println("========您正在查询数据==========");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return rs;
}
用户代理对象测试类/ProxyTest02
@Test
public void test(){
//创建用户代理对象
UserService userService = UserAgent.getProxy(new UserServiceImpl());
System.out.println(userService.login("admin", "123456"));
System.out.println(userService.selectUsers());
userService.deleteUsers();
}