即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

Java语言动态代理

编程语言 qq_34622600 46℃ 0评论

代理模式 


代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 


按照代理的创建时期,代理类可以分为两种。 


静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 


动态代理:在程序运行时,运用反射机制动态创建而成。 

先来个接口(JDK动态代理是基于接口的)

package proxyTest;

public interface Count {

 void queryCount();
 
 void updateCount();
}



实现类

package proxyTest;

public class CountImpl implements Count{

 @Override
 public void queryCount() {
  System.out.println("query count....");
  
 }

 @Override
 public void updateCount() {
  System.out.println("update count....");
 }

}

问题  要在查询之前之后做一些操作  比如记录日志  校验权限之类的

静态代理开始

package proxyTest;

public class CountProxy implements Count {

 
 Count count;
 
 public CountProxy(Count count ) {
  this.count = count;
 }
 @Override
 public void queryCount() {
  System.out.println("query start....");
  count.queryCount();
  System.out.println("query end....");
 }

 @Override
 public void updateCount() {
  System.out.println("update start....");
  count.updateCount();
  System.out.println("update end....");
 }

}



测试

Count count = new CountProxy(new CountImpl());
  count.queryCount();
  count.updateCount();



以上静态代理,可以简单粗暴的实现我们的要求,但是不好扩展,不方便。


下面介绍动态代理,其实原理是一样的

/**
 * JDK动态代理类
 * @author zhoushiwen
 *
 */
public class CountJDKProxy implements java.lang.reflect.InvocationHandler {

  private Object target;  
    /** 
     * 绑定委托对象并返回一个代理类 
     * @param target 
     * @return 
     */  
    public Object bind(Object target) {  
        this.target = target;  
        //取得代理对象  
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
                target.getClass().getInterfaces(),  this);   
    }  
 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  Object o = null;
  System.out.println("开始。。。。");
  o = method.invoke(target, args);
  System.out.println("结束。。。。");
  return o;
 }

}

注意:JDK的代理对象必须实现接口,有一定的局限性。cglib弥补了这一缺陷


测试

CountJDKProxy cjp = new CountJDKProxy();


  Count count = (Count) cjp.bind(new CountImpl());


count.queryCount();


count.updateCount();

spring的AOP也是利用动态代理实现的




转载请注明:CodingBlog » Java语言动态代理

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情