Java动态代理
案例
模拟企业业务功能开发,并完成每个功能的性能统计
需求:
- 模拟某企业用户管理业务,需包含用户登录,用户删除,用户查询功能,并要统计每个功能的耗时。
分析:
- 定义一个UserService表示用户业务接口,规定必须完成用户登录,用户删除,用户查询功能。
- 定义一个实现类UserServiceImpl实现UserService,并完成相关功能,且统计每个功能的耗时。
- 定义测试类,创建实验类对象,调用方法。
UserService:
1 2 3 4 5 6 7 8 9 10
| package CC.Proxy;
public interface UserService { String login(String loginName,String passWord); void selectUsers(); boolean deleteUsers(); }
|
UserviceImpl:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package CC.Proxy;
public class UserServiceImpl implements UserService{
@Override public String login(String loginName, String passWord) { long startTimer = System.currentTimeMillis(); try { Thread.sleep(1000); if("admin".equals(loginName) && "1234".equals(passWord)){ return "success"; } return "登录名和密码可能有毛病"; } catch (Exception e){ e.printStackTrace(); return "error"; } finally { long endTimer = System.currentTimeMillis(); System.out.println("login方法耗时: " + (endTimer-startTimer)/1000.0 + "s"); } }
@Override public void selectUsers() { long startTimer = System.currentTimeMillis(); System.out.println("查询了100个用户数据!"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } long endTimer = System.currentTimeMillis(); System.out.println("selectUsers方法耗时: " + (endTimer-startTimer)/1000.0 + "s"); }
@Override public boolean deleteUsers() { long startTimer = System.currentTimeMillis(); try { System.out.println("删除了100个用户数据!"); Thread.sleep(500); return true; } catch (InterruptedException e) { e.printStackTrace(); return false; }finally { long endTimer = System.currentTimeMillis(); System.out.println("deleteUsers方法耗时: " + (endTimer-startTimer)/1000.0 + "s"); } } }
|
Test:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package CC.Proxy;
public class Test { public static void main(String[] args) { UserService userService = new UserServiceImpl(); System.out.println(userService.login("admin","1234")); userService.selectUsers(); System.out.println(userService.deleteUsers()); } }
|
本案例存在哪些问题?
业务对象的每个方法 都要进行性能统计,存在大量重复的代码。
使用动态代理解决问题
动态代理
- 代理就是被代理者没有能力或者不愿意去完成某件事情,需要找个人代替自己去完成这件事,动态代理就是用来对业务功能(方法)进行代理的 。
关键步骤


把这里创立的对象传入代理中,返回一个代理对象回来
ProxyUtil代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package CC.Proxy;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
public class ProxyUtil {
public static UserService getProxy(UserService obj) { return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long startTimer = System.currentTimeMillis(); Object result = method.invoke(obj,args);
long endTimer = System.currentTimeMillis(); System.out.println(method.getName() + "方法耗时: " + (endTimer-startTimer)/1000.0 + "s");
return result; } }); } }
|

最后,在正常逻辑业务中,即可不再重复写性能统计的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package CC.Proxy;
public class UserServiceImpl implements UserService{
@Override public String login(String loginName, String passWord) {
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if("admin".equals(loginName) && "1234".equals(passWord)){ return "success"; } return "登录名和密码可能有毛病"; }
@Override public void selectUsers() { System.out.println("查询了100个用户数据!"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } }
@Override public boolean deleteUsers() { try { System.out.println("删除了100个用户数据!"); Thread.sleep(500); return true; } catch (InterruptedException e) { e.printStackTrace(); return false; } }
@Override public void updateUsers() { try { System.out.println("修改了100个用户!"); Thread.sleep(2500); } catch (InterruptedException e) { e.printStackTrace(); } } }
|
想要增添其他方法的时候,只需写正常的业务逻辑代码,无需再写性能统计的代码。达到动态代理的效果
