Java中的动态代理
2016-08-28 21:02
337 查看
动态代理:运行过程中根据传来的参数动态的在内存中创建代理类。
模式图:
上图中没有看到代理类,在动态代理中代理类都是更加LogHandler中的newProxyInctance方法中的对象参数在内存中实时的实例化出来的。Java本身对该模式有实现,会应用到Proxy类和InvocationHandler,下面通过实例来看一下动态代理是如何实际应用的。
首先还是要有一个接口,及接口的实现类,这个实现类也就是会被代理的类,如下:
接口————
实现————
创建一个类实现InvocationHandler接口,代码如下:
Proxy类:
Proxy.newProxyInstance(Class Loader loader, Class<?>[] interfaces, InvocationHandler h);
Loader:被代理对象的类加载器,可以通过Object.getClass().getClassLoader()获取。
Interface:被代理类实现的接口,通过该参数被创建的动态代理中会有和被代理对象一样的方法。
h:实现了InvocationHandler接口的类,一般都是我们创建的实现类本身,所以直接传this即可。
InvocationHandler接口:
该接口中有一个invoke(Objectproxy, Method method, Object[] args)方法,该方法是动态
代理被调用了代理的方法后回调的函数。
Method:被调用的方法
Args:被调用的方法所有的参数
当回调到invoke方法是用动态的调用被代理对象中有具体实现的方法,用的是method.invoke(Object obj, Object... args);
Obj:被代理的对象
Args:方法中的参数。
客户端调用:
整个的流程如下:
客户端调用LogHandler的方法会返回一个代理类,当调用方法是调用的是代理类中的方法,不论调用什么方法代理类都会回调LogHandler中的invoke方法,在invoke方法中可以调用真实类的方法,然后将结果一层一层的返回。
小结:
动态代理模式解决了静态代理模式扩展过多类的问题,但是动态代理会影响性能要适当使用。实例展示的是打印规定内容,而Spring中的AOP打印日志就是动态代理的实现,总结相关博客进一步了解动态代理和AOP的实现原理。
模式图:
上图中没有看到代理类,在动态代理中代理类都是更加LogHandler中的newProxyInctance方法中的对象参数在内存中实时的实例化出来的。Java本身对该模式有实现,会应用到Proxy类和InvocationHandler,下面通过实例来看一下动态代理是如何实际应用的。
首先还是要有一个接口,及接口的实现类,这个实现类也就是会被代理的类,如下:
接口————
<span style="font-size:18px;">public interface UserManager { public voidaddUser(String userId, String userName); public voiddelUser(String userId); }</span>
实现————
<span style="font-size:18px;">public class UserManagerImpl implements UserManager { public voidaddUser(String userId, String userName) { System.out.println("UserManagerImpl.addUser()userId-->>" + userId); } public voiddelUser(String userId) { System.out.println("UserManagerImpl.delUser()userId-->>" + userId); } }</span>
创建一个类实现InvocationHandler接口,代码如下:
<span style="font-size:18px;">public class LogHandler implements InvocationHandler { private ObjecttargetObject; public ObjectnewProxyInstance(Object targetObject) { this.targetObject= targetObject; returnProxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(),this); } public Objectinvoke(Object proxy, Method method, Object[] args) throwsThrowable { System.out.println("start-->>"+ method.getName()); for (inti=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(Exceptione) { e.printStackTrace(); System.out.println("error-->>"+ method.getName()); throwe; } return ret; } }</span>
Proxy类:
Proxy.newProxyInstance(Class Loader loader, Class<?>[] interfaces, InvocationHandler h);
Loader:被代理对象的类加载器,可以通过Object.getClass().getClassLoader()获取。
Interface:被代理类实现的接口,通过该参数被创建的动态代理中会有和被代理对象一样的方法。
h:实现了InvocationHandler接口的类,一般都是我们创建的实现类本身,所以直接传this即可。
InvocationHandler接口:
该接口中有一个invoke(Objectproxy, Method method, Object[] args)方法,该方法是动态
代理被调用了代理的方法后回调的函数。
Method:被调用的方法
Args:被调用的方法所有的参数
当回调到invoke方法是用动态的调用被代理对象中有具体实现的方法,用的是method.invoke(Object obj, Object... args);
Obj:被代理的对象
Args:方法中的参数。
客户端调用:
<span style="font-size:18px;">public class Client { publicstatic void main(String[] args) { LogHandlerlogHandler = new LogHandler(); UserManageruserManager = (UserManager)logHandler.newProxyInstance(new UserManagerImpl()); userManager.addUser("0001","张三"); } }</span>
整个的流程如下:
客户端调用LogHandler的方法会返回一个代理类,当调用方法是调用的是代理类中的方法,不论调用什么方法代理类都会回调LogHandler中的invoke方法,在invoke方法中可以调用真实类的方法,然后将结果一层一层的返回。
小结:
动态代理模式解决了静态代理模式扩展过多类的问题,但是动态代理会影响性能要适当使用。实例展示的是打印规定内容,而Spring中的AOP打印日志就是动态代理的实现,总结相关博客进一步了解动态代理和AOP的实现原理。
相关文章推荐
- 使用JAVA中的动态代理实现数据库连接池 Z
- 使用Java动态代理实现AOP
- 使用JAVA中的动态代理实现数据库连接池
- 使用JAVA中的动态代理实现数据库连接池
- 用Java动态代理实现AOP
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP
- Java动态代理实现AOP
- AOP系列之三:用Java动态代理实现AOP [zz]
- 迈出AOP第一步--使用Java 动态代理实现AOP[zz]
- 使用JAVA中的动态代理实现数据库连接池
- 使用JAVA中的动态代理实现数据库连接池
- Java动态代理实现
- 用Java动态代理实现AOP
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP
- 用Java动态代理实现AOP
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP(转)
- 使用java 动态代理去掉代码中的bad smell。
- 使用JAVA中的动态代理实现数据库连接池
- AOP初学者第一步:用Java动态代理实现AOP
- 动态代理(Dynamic Proxy)Java Servlet