Java中的动态代理

来源:互联网 发布:淘宝上信用卡套现吗 编辑:程序博客网 时间:2024/06/01 07:30

     代理模式我们在学大话的时候已经接触过了,代理为其他对象提供一种代理,以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。java中根据代理类的创建时期,可以分为静态代理和动态代理之分。


静态代理

由我们自己创建的代理类,再对其进行编译。程序运行前,代理类就已经存在。如:


接口类

<span style="font-size:18px;">//接口类public interface  UserManager{public void addUser(String username,String password);}</span>

实现接口的子类

//声明实现接口的子类public class UserManagerImpl implements UserManager {@Overridepublic void addUser(String username, String password) {//checkSecuritySystem.out.println("----UserManagerImpl.add()--------");}


代理类

//声明一个实现接口的代理类public class UserManagerImplProxy implements UserManager{//引用一个实现接口的类private UserManager userManager;public UserManagerImplProxy(UserManager userManager){this.userManager=userManager;}@Overridepublic void addUser(String username, String password) {checkSecurity();  //可以调用其它的方法userManager.addUser(username, password);System.out.println("随意添加事后处理消息");}

客户端调用

<span style="font-size:18px;">//客户端调用public class TestUser{      public static void main(String[] args) {          UserManagerImpl userImpl= new UserManagerImpl ();          UserManagerImplProxy userProxy = new UserManagerImplProxy (userImpl);          userProxy .addUser();      }  }  </span><span style="font-size:14px;"></span>

 
  由代码可知,静态代理类与被代理类都要实现同一个接口。如果类比较多的话,就需要建立多个代理类,而代理类中有很多方法都是重复的,这时就需要使用动态代理

动态代理

JDK它是利用Java反射机制实现的。JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,降低类之间的藕合性。 

   如: 接口类与实现类与上面一样。

动态代理包含一个类和一个接口,java.lang.reflect包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。

<span style="font-family:SimSun;font-size:14px;">import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class SecurityHandler implements InvocationHandler {private Object targetObject;public Object createProxyInstance(Object targetObject){this.targetObject=targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  targetObject.getClass().getInterfaces(), this) ;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {//调用目标方法Object ret =method.invoke(targetObject, args);return ret;}}</span>
    这里Proxy.newProxyInstance()会通过提供的ClassLoader和interface列表来产生代理类。method.invoke(owner, args):执行该Method.invoke方法的参数是执行这个方法的对象owner,和参数数组args,可以这么理解:owner对象中带有参数args的method方法。返回值是Object,也既是该方法的返回值。相当于owner.method(args)

客户端调用

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class Client {public static void main(String[] args){SecurityHandler hander =new SecurityHandler();UserManager userManager =(UserManager)hander.createProxyInstance(new UserManagerImpl());userManager.modifyUser(1,"张三", "123");}}</span>

小结:

  动态代理实现了日志和业务的分开,如spring中的AOP思想,。它是对面向对象思想的一种补充。面向对象思想强调的主要是封装,是抽象。而对于次要的,没有抽象的东西就不必和它在一起。动态代理就可以把这次次要的东西按照面向对象的思想进行归类。



0 0