设计模式____代理模式(静态代理,动态代理)

来源:互联网 发布:中企动力java面试 编辑:程序博客网 时间:2024/05/22 15:27

1.代理模式的作用

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

2.应用场景

在Spring中IOC和AOP模式的实现 先说Struts的IOC原理和SpringIOC一样 Struts2的拦截器原理和Spring AOP一样

IOC基于java的反射机制 AOP基于java的代理机制

2.代码

//================================静态代理=================================================\\

.一个单纯的唱歌的接口

package com.staticproxy.test;public interface Song {public void singSong();}
         .歌手实现唱歌的接口

package com.staticproxy.test;public class Singer implements Song{@Overridepublic void singSong() {System.out.println("菊花残 ...满地伤........");}}
        .经纪人开始接活

package com.staticproxy.test;/** * @author Administrator * 经纪人 */public class ProxyPerson implements Song{private Singer singer;@Overridepublic void singSong() { System.out.println("代理人(经纪人)和广告上谈好价格 10万元一首歌....");  System.out.println("杰伦开始唱鸡毛..."); //歌手开始唱 singer=new Singer(); singer.singSong(); System.out.println("ok 收钱啦 3,7分");}}
          ..测试

package com.staticproxy.test;/** * @author Administrator * 代理类:房产中介,经纪人,哈哈 老鸨 * 被代理的:买房的,明星,小xx */public class TestStaticProxy {public static void main(String[] args) {ProxyPerson person=new ProxyPerson();person.singSong();}}
           .运行结果



//===============================动态代理=================================\\

package com.activeproxy.test;/** * @author Administrator * 一个普通的接口 */public interface StudentService {public void add();}
package com.activeproxy.test;/** * @author Administrator * 一个普通的接口实现类 */public class StudentServiceImpl implements StudentService{public void add() {System.out.println("我是接口实现类..我实现了接口的方法....");}}
package com.activeproxy.test;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class MyHandler implements InvocationHandler {//代理对象Object proxyObj = null;// no param constructor methodpublic MyHandler() {super();}// constructor by parampublic MyHandler(Object proxyObj) {super();this.proxyObj = proxyObj;}// 代理方法public Object invoke(Object obj, Method method, Object[] objparam)throws Throwable {// 执行目标对象的方法之前 打印一下System.out.println(".............before.............");Object result = method.invoke(proxyObj, objparam);System.out.println(".............after.............");return result;}}
package com.activeproxy.test;import java.lang.reflect.Proxy;/** * 第一步>>我们要有一个接口,还要有一个接口的实现类,而这个实现类呢就是我们要代理的对象, * 所谓代理呢也就是在调用实现类的方法时,可以在方法执行前后做额外的工作,这个就是代理 * 第二步>>我们要自己写一个在要代理类的方法执行时,能够做额外工作的类,而这个类必须继承InvocationHandler接口 * 为什么要继承它呢?因为代理类的实例在调用实现类的方法的时候,不会调真正的实现类的这个方法, * 而是转而调用这个类的invoke方法(继承时必须实现的方法),在这个方法中你可以调用真正的实现类的这个方法 * 这里要解释下中部那段长长的代码的意思,以及具体做了哪些工作? * 第一,根据us.getClass().getClassLoader()这个要代理类的类加载器和 * us.getClass().getInterfaces()要代理类所实现的所有的接口 * 作为参数调用Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces) * 的方法返回代理类的java.lang.Class对象,也就是得到了java动态生成的代理类$Proxy0的Class对象。 * 同时,java还让这个动态生成的$Proxy0类实现了要代理类的实现的所有接口,并继承了Proxy接口。 * 第二,实例化这个动态生成的$Proxy0类的一个实例,实例化代理类的构造函数为Proxy(InvocationHandler h), * 也就是说要实例化这个动态生成的$Proxy0类,必须给它一个InvocationHandler参数,也就是我们自己实现的用来在代理类 * 方法执行前后做额外工作的类MyHandler。 * 这段代码Proxy.newProxyInstance(us.getClass().getClassLoader(),us.getClass().getInterfaces(), new MyHandler(us)) * 得到的其实是一个类名叫$Proxy0 extends Proxy implements * StudentService的类。 第三,将这个$Proxy0类强制转型成StudentService类型,调用add方法。 */public class TestPro {public static void main(String[] args) throws Throwable {//获取接口的实例化对象// 创建代理对象(就是是 接口  接口应用变量(proxyObj) = new  实现类)//得到 代理类  StudentServiceImpl //绑定 Myhander 处理类StudentService us = new StudentServiceImpl();//不是让接口引用 去掉方法 而是 让处理类hander掉用StudentService proxy = (StudentService)Proxy.newProxyInstance(us.getClass().getClassLoader(),us.getClass().getInterfaces(), new MyHandler(us));//StudentService proxy = (StudentService)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),us.getClass().getInterfaces(), new MyHandler(us));proxy.add();}}

//运行结果








阅读全文
0 0