1. 在java.lang.reflect包下,定义了自己的代理。利用这个包下的类,我们可以在运行时动态地创建一个代理类,实现一个或多个接口。并将方法的调用转发到你所指定的类。因为实际代理是在运行时创建的,所以称为:动态代理。
Proxy:完全由java产生的,而且实现了完整的subject接口。
InvocationHandler:Proxy上的任何方法调用都会被传入此类,InvocationHandler控制对RealSubject的访问。
因为Java已经帮助我们创建了Proxy类,我们需要有办法告诉Proxy类你要做什么,我们不能像以前一样把代码写入到Proxy类中,因为Proxy类不是我们实现的。那么我们应该放在哪里?放在InvocationHandler类中,InvocationHandler类是响应代理的任何调用。我们可以吧InvocationHandler想成是代理收到方法调用后,请求做实际工作的对象。
2. java.lang.reflect.InvocationHandler
被代理实例所实现的一个接口,内部只有一个invoke()方法,签名如下;
Java代码
public Object invoke(Object proxy, Method method, Object[] args)
当代理的方法被调用的时候,代理就会把这个调用转发给InvocationHandler,也就会调用它的invoke()方法。
3. java.lang.reflect.Proxy
提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类,我们经常使用的静态方式是:
Java代码
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
4. 示例:
情形:自己可以查看修改姓名性别,但是不能修改rate。他人可以查看姓名,性别以及修改rate,但是不能修改姓名性别。
1、接口
public interface Person {
String getName();
String getGender();
void setName(String name);
void setGender(String gender);
void setRate(int rate);
int getRate();
}
2、实现类
public class PersonImpl implements Person {
String name;
String gender;
String interests;
int rate;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getInterests() {
return interests;
}
public void setInterests(String interests) {
this.interests = interests;
}
public int getRate() {
return rate;
}
public void setRate(int rate) {
this.rate = rate;
}
}
3、定义OwnerInvocationHandler类,表示如果为本人,则可以进行修改查看姓名性别。
public class OwnerInvocationHandler implements InvocationHandler {
private Person personBean;
public OwnerInvocationHandler(Person personBean) {
this.personBean = personBean;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws IllegalAccessException {
try {
if (method.getName().startsWith("get")) {// 如果方法名为get,就调用person类内的get相应方法
return method.invoke(personBean, args);
} else if (method.getName().equals("setRate")) { // 如果方法是setRate,则抛出异常
throw new IllegalAccessException("access deny");
} else if (method.getName().startsWith("set")) { // 如果为set,就调用person类内的set相应方法
return method.invoke(personBean, args);
} else {
System.out.println("non method invoke");
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
4、定义NonInvocationHandler类,表示如果不为本人,则可以进行查看姓名性别和修改rate
public class NonInvocationHandler implements InvocationHandler {
private Person person;
public NonInvocationHandler(Person person) {
this.person = person;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName().startsWith("setRate")) {
return method.invoke(person, args);
} else if (method.getName().startsWith("get")) {
return method.invoke(person, args);
} else {
System.out.println("non method invoke");
return null;
}
}
}
5、测试类
public class MyDynamicProxy {
public Person getOwnerPersonBeanProxy(Person person) {
return (Person) Proxy.newProxyInstance(person.getClass()
.getClassLoader(), person.getClass().getInterfaces(),
new OwnerInvocationHandler(person));
}
public Person getNonPersonBeanProxy(Person person) {
return (Person) Proxy.newProxyInstance(person.getClass()
.getClassLoader(), person.getClass().getInterfaces(),
new NonInvocationHandler(person));
}
public static void main(String[] args) {
MyDynamicProxy mdp = new MyDynamicProxy();
mdp.test();
}
public void test() {
//
Person person = getPersonBeanFromDB1();
Person personProxy = getOwnerPersonBeanProxy(person);
System.out.println(personProxy.getName());
try {
personProxy.setRate(2);
} catch (Exception e) {
System.out.println("can not setRate");
}
//
Person person1 = getPersonBeanFromDB1();
Person personProxy2 = getNonPersonBeanProxy(person1);
System.out.println(personProxy2.getName());
personProxy2.setRate(2);
System.out.println(personProxy2.getRate());
}
private Person getPersonBeanFromDB1() {
Person pb = new PersonImpl();
pb.setName("remy");
pb.setGender("girl");
pb.setRate(1);
return pb;
}
}
还可以参考 http://www.iteye.com/topic/961057
http://www.iteye.com/topic/1116657
写的非常好!
分享到:
相关推荐
《HeadFirst设计模式学习笔记》是一份详尽的资料,旨在帮助读者深入理解并掌握设计模式这一编程领域的核心概念。设计模式是软件工程中的一种最佳实践,它在解决常见问题时提供了一种标准的解决方案,使得代码更易于...
通过上述对Head First设计模式学习笔记的解析,我们可以看到每种模式都在特定场景下发挥了重要作用,帮助开发者更好地组织代码,提高程序的可扩展性和可维护性。在实际项目中灵活运用这些设计模式,可以有效提升软件...
《HeadFirst设计模式学习笔记1--策略模式Demo》 在软件工程中,设计模式是一种解决常见问题的标准方案,它提供了一种在特定情况下组织代码的模板。策略模式是设计模式中的一种行为模式,它允许在运行时选择算法或...
在“HeadFirst 设计模式学习笔记3--装饰模式 Demo”中,作者通过实例讲解了装饰模式的基本概念、结构和应用场景。这篇文章可能是从CSDN博客平台上的一个链接访问的,遗憾的是,由于我们当前无法直接访问该链接,所以...
总的来说,HeadFirst设计模式的学习笔记2关于观察者模式的演示,旨在帮助开发者理解如何使用观察者模式来构建可扩展的系统。通过实际的代码示例,我们可以更深入地掌握这一模式,并将其应用到日常开发中,提升代码的...
### Head.First 设计模式学习笔记知识点总结 #### 一、设计模式概述 设计模式是一种用于解决软件设计中常见问题的标准化方法。通过采用设计模式,开发者可以提高代码的复用性、灵活性和可维护性。《Head First 设计...
在《Head First 设计模式学习笔记(十四)模式的组合使用》中,作者探讨了如何在实际编程中灵活地组合多种设计模式以解决复杂问题。这篇文章可能是基于《Head First 设计模式》这本书的一个章节,该书是设计模式领域...
《Head First 设计模式》是软件开发领域内一本广受欢迎的书籍,由Eric Freeman、Elisabeth Robson、Bert Bates和Kathy Sierra四位作者共同撰写。这本书以其独特的视觉风格和易于理解的教学方法,深入浅出地介绍了...
读书笔记:设计模式学习笔记和代码。《图解设计模式》《Head First 设计模式》
《HeadFirst设计模式笔记》是深入理解软件设计思想的一份宝贵资料,主要涵盖了设计模式的基础理论和实际应用。设计模式是软件开发中的经验总结,它为解决常见的编程问题提供了标准的解决方案,使得代码更具可读性、...
本项目为《Head First 设计模式》的Java语言学习笔记与实战练习源码集合,包含104个文件,主要包括88个Java源文件、12个Markdown文档、3个XML配置文件及少量其他辅助文件。内容涵盖设计模式的学习笔记以及相应的代码...
《Head First设计模式》是一本深受开发者喜爱的设计模式学习书籍,它以易懂且生动的方式介绍了23种经典设计模式。这些模式是软件工程中经过实践验证的最佳实践,旨在提高代码的可重用性、可读性和可维护性。下面,...
著名的《Head First Design Pattern》学习笔记,摘要这本书中的设计思路。由于书本过长,整理出笔记帮助回想起设计模式。文件是docx格式,只能由OFFICE Word 2007之后的版本打开,内附Visio类图文件。本文由个人整理...
以上只是《Head First Servlets & JSP》一书中的部分核心知识点,实际内容还包括过滤器、监听器、MVC设计模式、JSTL等更广泛的主题,旨在帮助读者全面理解和掌握Servlet和JSP技术。通过深入学习,开发者能够构建高效...
通过以上对“Head First设计模式”书中可能涉及的设计模式的介绍,我们可以看出这本书是学习面向对象设计模式的绝佳资源。无论是初学者还是有一定经验的开发人员,都能从中受益匪浅。理解并熟练运用这些模式能够帮助...
【Servlet&JSP基础知识】 ...以上是`head_first_servlet&jsp`学习笔记的主要知识点,涵盖了Servlet和JSP的基础、Web应用架构、MVC模式、会话管理和JSP编程等多个方面,为深入理解和实践Servlet与JSP开发奠定了基础。
本学习笔记将深入探讨如何在C#中创建事件,以实现一个棒球模拟系统的例子。在这个系统中,我们将关注投球手、观众和裁判的交互,当输入棒球的轨迹和距离时,这些对象会根据模拟结果做出相应的反应。 首先,理解事件...
设计模式Head First学习笔记,以及使用java编写的设计模式源码,Java原生sdk实现23种设计模式
《Head First 策略者模式》学习笔记 策略者模式是一种行为设计模式,它使你能在运行时改变对象的行为。在软件开发中,我们常常遇到需要根据不同的情况执行不同算法的问题。策略者模式就是为了解决这类问题而生,它...