JDK动态代理

来源:互联网 发布:linux vi命令退出编辑 编辑:程序博客网 时间:2024/06/07 20:20

http://rejoy.iteye.com/blog/1627405

这篇文章说的够详细了。但是对照传智播客那个视频,貌似有点问题。

return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),                   target.getClass().getInterfaces(), this); 

上面的类加载器,视频中推荐是用目标对象的类加载器。

return Proxy.newProxyInstance(target.getClass.getClassLoader().getContextClassLoader(),                   target.getClass().getInterfaces(), this); 

还有,把那个代理类改个名字好点,改成某某工厂类,不然听着怪难受的。

package dynamic.proxy;     import java.lang.reflect.InvocationHandler;  import java.lang.reflect.Method;  import java.lang.reflect.Proxy;    /**  * 实现自己的InvocationHandler  * @author zyb  * @since 2012-8-9  *  */  public class MyInvocationHandler implements InvocationHandler {            // 目标对象       private Object target;            /**      * 构造方法      * @param target 目标对象       */      public MyInvocationHandler(Object target) {          super();          this.target = target;      }          /**      * 执行目标对象的方法      */      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                    // 在目标对象的方法执行之前简单的打印一下          System.out.println("------------------before------------------");                    // 执行目标对象的方法          Object result = method.invoke(target, args);                    // 在目标对象的方法执行之后简单的打印一下          System.out.println("-------------------after------------------");                    return result;      }        /**      * 获取目标对象的代理对象      * @return 代理对象      */      public Object getProxy() {          return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),                   target.getClass().getInterfaces(), this);      }  } 

改成:

package cn.itcast.service.impl;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * @author Administrator * JDK动态代理工厂。根据目标对象生成代理对象 */public class JDKProxyFactory implements InvocationHandler{//要代理的对象private Object targetObject;//负责生成代理对象的工厂方法public Object createProxyObject(Object object){//生成PersonServiceBean的代理对象this.targetObject = object;Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);return null;}//代理对象,在获知要调用目标对象的方法时,会回调该方法。在该方法中,代理对象要把对目标对象的操作,委派目标对象执行。/* * 有一台打印机(目标对象)实现3C标准(接口,没有质量保证,谁敢用),具有打印功能(方法)。 * 有一个会操作打印机的人(代理对象),店主。 * 现在有人来打印,就叫店主帮他打印。店主知道了客人要求要打印(请求) * 可是店主自己本身不能打印啊(会打印还得了),核对一下打印的文件(打印前), * 只能给打印机输入打印指令和参数,让他进行打印(委派目标对象进行处理),收集文件(打印后) *  */@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object result ;// TODO Auto-generated method stubSystem.out.println("目标对象执行方法前");result = method.invoke(targetObject, args);System.out.println("目标对象执行方法后");return result;}}
测试代码:

package junit.test;import static org.junit.Assert.*;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.itcast.service.PersonService;import cn.itcast.service.impl.JDKProxyFactory;import cn.itcast.service.impl.PersonServiceBean;public class SpringTest {@Testpublic void jdkProxyTest(){ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});PersonService bean = (PersonServiceBean)ctx.getBean("personService1");//这里就不同过容器进行创建PersonService了JDKProxyFactory jf = new JDKProxyFactory();//因为代理对象实现了目标对象的所有接口,所以也可以生产的代理对象也是可以赋值给PersonSercvicePersonService personService2 = (PersonService) jf.createProxyObject(bean);personService2.save();}}



0 0
原创粉丝点击