Jdk 动态代理(一个实际案例使用)
来源:互联网 发布:实用五金工具手册软件 编辑:程序博客网 时间:2024/06/15 21:04
Jdk 动态代理:利用java的反射,允许运行时动态地创建一个代理类,实现一个或多个接口,将方法的调用转发到你所指定的类。
问题场景:
有一个Person类,其中属性字段有:姓名name、性别gender、兴趣interests、评分值hotOrNotRating,要求:get方法所有字段,对于所有该类实例拥有者或者非该类实例拥有者都有效,而该类实例拥有者除了不能给自己评分之外,可以修改所有的其他字段,而非该类实例拥有者只能设置该评分值,而不能修改其他所有的字段。
利用Java动态代理实现代码如下:
PersonBean.java 类如下:
public interface PersonBean { String getName(); // 取得人的名字 String getGender(); // 性别 String getInterests(); // 兴趣 int getHotOrNotRating(); // HotOrNot评分(1到10) void setName(String name); void setGender(String name); void setInterests(String interests); void setHotOrNotRating(int rating);}
PersonBeanImpl.java 类如下:
public class PersonBeanImpl implements PersonBean { String name; String gender; String interests; int rating; //当前的评价分数 int ratingCount = 0; // 当前的评价数 @Override public String getName() { return name; } @Override public String getGender() { return gender; } @Override public String getInterests() { return interests; } @Override public int getHotOrNotRating() { if (ratingCount == 0) return 0; return (rating/ratingCount); } @Override public void setName(String name) { this.name = name; } @Override public void setGender(String name) { this.gender = gender; } @Override public void setInterests(String interests) { this.interests = interests; } @Override public void setHotOrNotRating(int rating) { this.rating += rating; ratingCount++; }}
拥有者使用类的情况:
OwnerInvocationHandler.java 类如下:
** * 拥有者使用类的情况 */public class OwnerInvocationHandler implements InvocationHandler { PersonBean person; public OwnerInvocationHandler(PersonBean person){ this.person = person; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException { try { if (method.getName().startsWith("get")){ return method.invoke(person, args); } else if (method.getName().equals("setHotOrNotRating")) { throw new IllegalAccessException(); } else if (method.getName().startsWith("set")) { return method.invoke(person, args); } } catch (InvocationTargetException e) { // 真正主题抛出异常 e.printStackTrace(); } return null; // 如果调用其他的方法,一律不理,返回null }}
非拥有者使用类如下:
NonOwnerInvocationHandler.java 类如下:
public class NonOwnerInvocationHandler implements InvocationHandler { PersonBean person; public NonOwnerInvocationHandler(PersonBean person) { this.person = person; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException { try { if (method.getName().startsWith("get")){ return method.invoke(person, args); } else if (method.getName().equals("setHotOrNotRating")) { return method.invoke(person, args); } else if (method.getName().startsWith("set")) { throw new IllegalAccessException(); } } catch (InvocationTargetException e) { // 真正主题抛出异常 e.printStackTrace(); } return null; // 如果调用其他的方法,一律不理,返回null }}
测试类如下:
MatchMakikngTestDrive.java 类:
public class MatchMakingTestDrive { public static void main(String[] args) { MatchMakingTestDrive test = new MatchMakingTestDrive(); test.drive(); } public void drive() { PersonBean joe = new PersonBeanImpl(); joe.setName("tim"); joe.setGender("girl"); joe.setInterests("watch movies"); joe.setHotOrNotRating(0); PersonBean ownerProxy = getOwnerProxy(joe); System.out.println("Name is: " + ownerProxy.getName()); ownerProxy.setInterests("bowling, Go"); System.out.println("Interests set from owner proxy"); try { ownerProxy.setHotOrNotRating(10); } catch (Exception e) { System.out.println("Can't set rating from owner proxy"); } System.out.println("Rating is " + ownerProxy.getHotOrNotRating()); PersonBean nonOwnerProxy = getNonOwnerProxy(joe); System.out.println("Name is: " + nonOwnerProxy.getName()); try { nonOwnerProxy.setInterests("bowling, go"); } catch (Exception e) { System.out.println("Can't set interests from non owner proxy"); } nonOwnerProxy.setHotOrNotRating(3); System.out.println("Rating set from non owner proxy"); System.out.println("Rating is " + nonOwnerProxy.getHotOrNotRating()); } PersonBean getOwnerProxy(PersonBean person) { return (PersonBean) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), new OwnerInvocationHandler(person)); } PersonBean getNonOwnerProxy(PersonBean person) { return (PersonBean) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), new NonOwnerInvocationHandler(person)); }}
输出:
Name is: tim
Interests setfrom owner proxy
Can't setrating from owner proxy
Rating is 0
Name is: tim
Can't setinterests from non owner proxy
Rating setfrom non owner proxy
Rating is 1
分析:
需要实现InvocationHandler接口,然后会自动覆盖如下方法:
public Object invoke(Object proxy,Method method, Object[] args)throws IllegalAccessException
在实现类中需要传入需要代理的类字段
在invoke方法中进行调用。
返回该类的实例:
return (PersonBean) Proxy.newProxyInstance(person.getClass().getClassLoader(),
person.getClass().getInterfaces(),
new OwnerInvocationHandler(person));
- Jdk 动态代理(一个实际案例使用)
- 使用 JDK 动态代理
- jdk代理(一) 静态代理和动态代理使用
- 动态代理(jdk)
- 使用jdk动态代理实例
- 动态代理(一)---JDK动态代理
- 一个案例,入门Java动态代理技术
- jdk动态代理(一)
- JDK动态代理(一)
- jdk动态代理(转载)
- Java动态代理(JDK)
- 动态代理(JDK + cglib)
- 动态代理(JDK实现)
- 简单动态代理实例(使用jdk的proxy)
- 代理模式二(JDK动态代理)
- JDK动态代理(接口的代理)
- Java代理(JDK动态代理)
- java代理(二)--jdk动态代理
- Python网络编程:实现心跳机制
- Javascript图片库(1)
- 1、调度的概念
- java泛型详细介绍
- 读一些论文有感。
- Jdk 动态代理(一个实际案例使用)
- Java List 、Set、Map集合总结
- 面向对象的三大特性:封装,继承,多态
- 用VMware虚拟机打开Ubuntu报错:“锁定文件失败”
- 在Ubuntu 16.04下安装Matlab 2017a
- centos7下安装oracle11g
- Java并发编程:CopyOnWriteArrayList
- JZOJ5454. 【NOIP2017提高A组冲刺11.5】仔细的检查
- 使用Scrapy爬取股票数据