1.动态代理:java在java.lang.reflect包中有自己的代理支持,利用这个包你可以在运行时动态的创建一个代理类,实现一个或者多个接口,并且将方法的调用转发到你指定的类。
保护代理:根据访问权限决定客户可否访问对象的代理。
2.任务:对象村的小伙伴们要相亲啦~请负责帮忙实现约会服务系统。
(1)PersonBean接口,允许设置或获取一个人的信息等。
1 public interface PersonBean { 2 public String getName() ; 3 public void setName(String name) ; 4 public String getGender() ; 5 public void setGender(String gender); 6 public String getInterests(); 7 public void setInterests(String interests) ; 8 public int getHotOrNotRating(); 9 public void setHotOrNotRating(int hotOrNotRating); 10 }
(2)实例化personBean。
1 public class PersonBeanImpl implements PersonBean { 2 String name; 3 String gender; 4 String interests; 5 int rating;//总分数 6 int ratingCount=0;//评分次数 7 public String getName() { 8 return name; 9 } 10 public void setName(String name) { 11 this.name = name; 12 } 13 public String getGender() { 14 return gender; 15 } 16 public void setGender(String gender) { 17 this.gender = gender; 18 } 19 public String getInterests() { 20 return interests; 21 } 22 public void setInterests(String interests) { 23 this.interests = interests; 24 } 25 public int getRating() { 26 return rating; 27 } 28 public void setHotOrNotRating(int rating) { 29 this.rating += rating; 30 ratingCount++; 31 } 32 public int getHotOrNotRating() { 33 if(ratingCount==0){ 34 return 0; 35 }else{ 36 return (rating/ratingCount); 37 } 38 } 39 }
那么问题来了:根据我们定义的方式,任何客户都可以调用任何方法。每个方法的返回信息都是公开的。但是在我们的相亲系统中,希望用户可以设置自己的信息,同时能防止别人修改。并且自己不能给自己打分,只能别人打分。
解决办法:必须创建两个代理,一个访问自己的PersonBean,一个访问别人的PersonBean,这样代理就可以控制在每一种情况下,允许哪一种请求。
3.动态代理创建
(1)创建InvocationHandler
InvocationHandler是调用处理器,当proxy的方法setName()被调用时,就会调用InvocationHandler的invoke()方法,然后handler来决定如何处理这个请求,可能是发给realSubject。因为有两个代理,所以要创建两个InvocationHandler。
1 import java.lang.reflect.*; 2 3 public class OwnerInvocationHandler implements InvocationHandler { 4 PersonBean personBean; 5 6 public OwnerInvocationHandler(PersonBean personBean) { 7 super(); 8 this.personBean = personBean; 9 } 10 11 12 public Object invoke(Object proxy, Method method, Object[] args) 13 throws IllegalAccessException { 14 15 try { 16 //唯独不能给自己打分 17 if(method.getName().equals("setHotOrNotRating")){ 18 throw new IllegalAccessException(); 19 } 20 else if(method.getName().startsWith("get")){ 21 //只要是get都可以 22 return method.invoke(personBean, args); 23 } 24 } catch (InvocationTargetException e) { 25 e.printStackTrace(); 26 } 27 28 return null; 29 } 30 31 }
1 import java.lang.reflect.*; 2 3 public class NonOwnerInvocationHandler implements InvocationHandler { 4 PersonBean personBean; 5 6 public NonOwnerInvocationHandler(PersonBean personBean) { 7 super(); 8 this.personBean = personBean; 9 } 10 11 12 public Object invoke(Object proxy, Method method, Object[] args) 13 throws IllegalAccessException { 14 15 try { 16 //get都可以 17 if(method.getName().startsWith("get")){ 18 return method.invoke(personBean, args); 19 } 20 //set只能是打分 21 else if(method.getName().equals("setHotOrNotRating")){ 22 return method.invoke(personBean, args); 23 } 24 else if(method.getName().startsWith("set")){ 25 //如果是其他set 26 throw new IllegalAccessException(); 27 } 28 } catch (InvocationTargetException e) { 29 e.printStackTrace(); 30 } 31 32 return null; 33 } 34 35 }
(2)写代码创建动态代理
(3)利用适当的代理包装任何PersonBean对象。
to be continued
时间: 2024-09-28 11:10:18