您的位置:首页 > 编程语言 > Java开发

java动态代理

2016-03-23 18:08 543 查看
                动态代理是程序运行期间由JVM根据反射机制动态生成。代理类和委托类的关系是在程序运行时确定。

          动态代理是程序运行期间由JVM根据反射机制动态生成。

             


           在上一篇博客静态代理的基础上修改为动态代理。

动态代理

清单一:代理接口
public interface UserManager {
public void addUser(String userId,String userName);

public void delUser(String userId);
}


清单二:委托类
public class UserManagerImpl implements UserManager {
public void addUser(String userId, String userName) {
try {
System.out.println("UserManagerImpl.addUser() userId-->>"+ userId);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}

public void delUser(String userId) {
System.out.println("UserManagerImpl.delUser() userId-->>"+ userId);
}
}

清单三:动态代理类
public class LogHandler implements InvocationHandler {
private Object targetObject;

public Object newProxyInstanceObject(Object targetObject) {
this.targetObject=targetObject;
return  Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("start-->>"+method.getName());
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}

Object retObject=null;
try{
//调用目标方法
method.invoke(targetObject, args);
System.out.println("success-->>"+method.getName());
}catch (Exception e) {
e.printStackTrace();
System.out.println("error-->>"+method.getName());
throw e;
}
return null;
}
}

          被代理对象targetObject通过参数传递进来,我们通过targetObject.getClass().getClassLoader()获取ClassLoader对象,然后通过targetObject.getClass().getInterfaces()获取它实现的所有接口,然后将targetObject包装到实现了InvocationHandler接口的LogHandler对象中。通过newProxyInstance函数我们就获得了一个动态代理对象。
 
          可以看到,我们可以通过LogHandler代理不同类型的对象,如果我们把对外的接口都通过动态代理来实现,那么所有的函数调用最终都会经过invoke函数的转发,因此我们就可以在这里做一些自己想做的操作,比如日志系统、事务、拦截器、权限控制等。这也就是AOP(面向切面编程)的基本原理。

清单四:客户类
public class Client {
public static void main(String[] args) {

LogHandler logHandler=new LogHandler();
UserManager userManager=(UserManager)logHandler.newProxyInstanceObject(new UserManagerImpl());
//userManager.addUser("0001", "张三");
//userManager.delUser("0001");
String name=userManager.findUser("0001");
System.out.println("Client.main() --- " +name);
}
}

动态代理的优缺点

          优点:动态代理和静态代理相比,最大的好处就是借口中声明的所有方法都被转移到调用处理器一个集中的方法(invoke)中处理。这样在借口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样,每一个方法进行中转。
          缺点:仅支持interface代理。由于java的集成机制注定了这些动态代理们无法实现对class的动态代理,因为java不能实现多继承。
 
          纵观静态代理与动态代理,它们都能实现相同的功能,而我们看从静态代理到动态代理的这个过程,我们会发现其实动态代理只是对类做了进一步抽象和封装,使其复用性和易用性得到进一步提升而这不仅仅符合了面向对象的设计理念,其中还有AOP的身影,这也提供给我们对类抽象的一种参考。关于动态代理与AOP的关系,个人觉得AOP是一种思想,而动态代理是一种AOP思想的实现!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: