1.代理模式的原理:
使用一个代理将对象包装起来, 然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。

2.静态代理
2.1 举例:
实现Runnable接口的方法创建多线程。

Class MyThread implements Runnable{} //相当于被代理类
Class Thread implements Runnable{} //相当于代理类
main(){
MyThread t = new MyThread();
Thread thread = new Thread(t);
thread.start();//启动线程;调用线程的run()
}

2.2 静态代理的缺点:
① 代理类和目标对象的类都是在编译期间确定下来,不利于程序的扩展。
② 每一个代理类只能为一个接口服务,这样一来程序开发中必然产生过多的代理。

3.动态代理的特点:
动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对
象。

4.动态代理的实现
4.1 需要解决的两个主要问题:
问题一:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象。
(通过Proxy.newProxyInstance()实现)
问题二:当通过代理类的对象调用方法a时,如何动态的去调用被代理类中的同名方法a。
(通过InvocationHandler接口的实现类及其方法invoke())
4.2 代码实现:

/**
*
* 动态代理的举例
*
* @author shkstart
* @create 2019 上午 10:18
*/ interface Human{ String getBelief(); void eat(String food); }
//被代理类
class SuperMan implements Human{ @Override
public String getBelief() {
return "I believe I can fly!";
} @Override
public void eat(String food) {
System.out.println("我喜欢吃" + food);
}
} class HumanUtil{ public void method1(){
System.out.println("====================通用方法一===================="); } public void method2(){
System.out.println("====================通用方法二====================");
} } class ProxyFactory{
//调用此方法,返回一个代理类的对象。解决问题一
public static Object getProxyInstance(Object obj){//obj:被代理类的对象
MyInvocationHandler handler = new MyInvocationHandler(); handler.bind(obj); return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);
} } class MyInvocationHandler implements InvocationHandler{ private Object obj;//需要使用被代理类的对象进行赋值 public void bind(Object obj){
this.obj = obj;
} //当我们通过代理类的对象,调用方法a时,就会自动的调用如下的方法:invoke()
//将被代理类要执行的方法a的功能就声明在invoke()中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { HumanUtil util = new HumanUtil();
util.method1(); //method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法
//obj:被代理类的对象
Object returnValue = method.invoke(obj,args); util.method2(); //上述方法的返回值就作为当前类中的invoke()的返回值。
return returnValue; }
} public class ProxyTest { public static void main(String[] args) {
SuperMan superMan = new SuperMan();
//proxyInstance:代理类的对象
Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
//当通过代理类对象调用方法时,会自动的调用被代理类中同名的方法
String belief = proxyInstance.getBelief();
System.out.println(belief);
proxyInstance.eat("四川麻辣烫"); System.out.println("*****************************"); NikeClothFactory nikeClothFactory = new NikeClothFactory(); ClothFactory proxyClothFactory = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory); proxyClothFactory.produceCloth(); }
}

体会:反射的动态性。

最新文章

  1. 无废话ExtJs 入门教程十七[列表:GridPanel]
  2. Redhat5.8 环境下编译安装 Redis 并将其注册为系统服务
  3. Android Studio编译运行project报错:····· finished with non-zero exit value 1
  4. Centos 如何安装Django环境
  5. E-R图向关系模式的转换
  6. php QQ登录
  7. Equivalent Strings (字符串相等?)
  8. Java Web开发: Tomcat中部署项目的三种方法
  9. Nagios安装部署
  10. 开放源代码的设计层面框架Spring——day03
  11. Spark启动报错|java.io.FileNotFoundException: File does not exist: hdfs://hadoop101:9000/directory
  12. 003_crlf注入漏洞
  13. 同构体字符串(如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。 所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。)
  14. Python之路,第十三篇:Python入门与基础13
  15. POJ3258--River Hopscotch(Binary Search similar to POJ2456)
  16. ASP.NET后台输出js脚本代码
  17. 【用jQuery来判断浏览器的类型】及【javascript获取用户ip地址】
  18. iOS7入门开发全系列教程新地址
  19. DRAM(动态)存储器
  20. linux命令创建和修改用户及密码

热门文章

  1. (二)log4j 配置详解
  2. mybatis 多表联查,多个实体类,如何返回一个List?(表太多,字段太多的问题)
  3. Java中泛型的继承
  4. LaTeX实时预览中文
  5. css3动画特效代码
  6. rust 编译器工作流
  7. Eplan PLC连接点模块为什么不显示“路径功能文本”,已解决
  8. Web前端 -- Webpack
  9. WeChair项目Beta冲刺(1/10)
  10. Mysql事务 JAVAGC 面试