什么是动态代理:
代理:代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。
动态代理的具体实现:
相关类与借口:
java.lang.reflect.Proxy:这是 Java 动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。
// 方法:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例 static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)java.lang.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。
- 代理类
- public class LogHandler implements InvocationHandler {
- private Object targetObject;
- public Object newProxyInstance(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 ret = null;
- try {
- //调用目标方法
- ret = method.invoke(targetObject, args);
- System.out.println("success-->>" + method.getName());
- }catch(Exception e) {
- e.printStackTrace();
- System.out.println("error-->>" + method.getName());
- throw e;
- }
- return ret;
- }
- }
- 接口类
- public interface UserManager {
- public void addUser(String userId, String userName);
- }
- 目标类
- package com.bjpowernode.pattern;
- public class UserManagerImpl implements UserManager {
- public void addUser(String userId, String userName) {
- //System.out.println("start-->>addUser() userId-->>" + userId);
- try {
- System.out.println("AddUser" );
- }
- }
- }
- 客户端
- public class Client {
- /**
- * @param args
- */
- public static void main(String[] args) {
- LogHandler logHandler = new LogHandler();
- UserManager userManager = (UserManager)logHandler.newProxyInstance(new UserManagerImpl());
- String name = userManager.AddUser("0001",”张三”); }
- }
动态代理与静态代理的区别:
由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成。无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。
哪些地方需要动态代理:
不允许直接访问某些类;对访问要做特殊处理等。或者,要对原方法进行统一的扩展,例如加入日志记录。