黑马程序员--java高新技术--动态代理
来源:互联网 发布:全球中文地图导航软件 编辑:程序博客网 时间:2024/05/29 15:09
------- android培训、java培训、期待与您交流! ---------
1.什么是代理?
一种用于转发请求,进行特殊处理的机制。“动态”指的是运行期。
2.为什么使用动态代理?
可以对请求进行任何处理
3.使用它有什么好处?
4.哪些地方需要动态代理?
不允许直接访问某些类,对访问要做特殊处理。
AOP面向方面的编程:
系统中存在许多交叉业务,一个交叉业务就是要切入到系统的一个方面。
同样的动作会在不同的模块中,这些动作就是模块的交叉业务。
可以把这些交叉业务都当做一个切面:
交叉业务的编程问题即为面向方面的编程(Aspect oriented program ,简称AOP),AOP的目标就是要使交叉业务模块化。可以采
用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果是一样的,如下所示:
使用代理技术可以解决aop的核心技术。
jvm可以在运行期动态生产出一个类,这种动态生成的类往往北用作代理,既动态代理。
动态类必须实现一个或多个接口。
CGLIB可以生成没有实现接口和类的动态代理。
package cn.jhc.day3;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.ArrayList;import java.util.Collection;public class ProxyTest {/** * @param args */public static void main(String[] args) throws Exception{// TODO Auto-generated method stub//Proxy.getProxyClass(类加载器, 接口)Class classProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);//System.out.println(classProxy1.getName());System.out.println("----begin constructors list ----");/* * $Proxy0() * $Proxy0(InvocationHandler,int) * *///获取类的所有构造方法。Constructor[] constructors = classProxy1.getConstructors();for (Constructor constructor : constructors) {//得到构造方法名String name = constructor.getName();StringBuilder sBuilder = new StringBuilder(name);//性能比buffer高sBuilder.append('(');//得到构造方法的参数Class[] classParams = constructor.getParameterTypes();for (Class classParam : classParams) {sBuilder.append(classParam.getName()).append(',');}if(classParams.length != 0 && classParams != null)sBuilder.deleteCharAt(sBuilder.length()-1);sBuilder.append(')');System.out.println(sBuilder.toString());}System.out.println("----begin methods list ----");/* * $Proxy0() * $Proxy0(InvocationHandler,int) * *///得到所有方法Method[] methods = classProxy1.getMethods();for (Method method : methods) {//得到方法名String name = method.getName();StringBuilder sBuilder = new StringBuilder(name);//性能比buffer高sBuilder.append('(');//得到方法的参数Class[] classParams = method.getParameterTypes();for (Class classParam : classParams) {sBuilder.append(classParam.getName()).append(',');}if(classParams.length != 0 && classParams != null)sBuilder.deleteCharAt(sBuilder.length()-1);sBuilder.append(')');System.out.println(sBuilder.toString());}System.out.println("----begin create instance object ----");//classProxy1.newInstance();//得到构造方法Constructor constructor = classProxy1.getConstructor(InvocationHandler.class);//InvocationHandler是一个接口//class MyInvocationHandler1 implements InvocationHandler{////@Override//public Object invoke(Object proxy, Method method, Object[] args)//throws Throwable {//// TODO Auto-generated method stub//return null;//}////}//Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHandler1());//System.out.println(proxy1);//proxy1.clear();////proxy1.size();////创建代理对象,创建匿名内部接口Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){//实现接口的invoke方法。@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn null;}});final ArrayList target = new ArrayList();Collection proxy3 = (Collection)getProxy(target,new MyAdvice());proxy3.add("zxx");proxy3.add("bxd");proxy3.add("bad");System.out.println(proxy3.size());}private static Object getProxy(final Object target,final Advice advice) {Object proxy3 = Proxy.newProxyInstance(target.getClass().getClassLoader(),//new Class[]{Collection.class},target.getClass().getInterfaces(),new InvocationHandler(){@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stub//long beginTime = System.currentTimeMillis();//Object retVal = method.invoke(target, args);//long endTime = System.currentTimeMillis();//System.out.println(method.getName() + " running time of " + (endTime - beginTime));//return retVal;//在目标前实现自己的方法advice.beforeMethod(method);Object retVal = method.invoke(target, args);//在目标后实现自己的方法advice.afterMethod(method);return retVal;}});return proxy3;}}
总结一下需要注意的地方:
目标方法要求返回的值类型与代理类返回的值类型应当保持一致;
newProxyInstance()方法可以得到一个动态代理类,它需要接受3个参数
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
Loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载。
Interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了。
h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上。
InvocationHandler中需要实现的invoke()方法接受三个参数
invoke(Object proxy, Method method,Object[] args)
proxy: 指代我们所代理的那个真实对象
method: 指代的是我们所要调用真实对象的某个方法的Method对象
args: 指代的是调用真实对象某个方法时接受的参数
这个invoke方法要用到这些参数的原因是:代理类要去找目标类的方法并调用,然后返回。
------- android培训、java培训、期待与您交流! ---------
- 黑马程序员java高新技术篇----动态代理
- 黑马程序员--java高新技术--动态代理
- 黑马程序员 java高新技术 代理
- 黑马程序员--java高新技术--动态代理技术的深入讲解
- 黑马程序员 java高新技术- 类加载器和动态代理
- 黑马程序员—JAVA高新技术之类加载器、动态代理
- 黑马程序员--java高新技术----动态代理及AOP
- 黑马程序员—JAVA高新技术_动态代理
- 黑马程序员---高新技术之动态代理类
- 黑马程序员--高新技术之动态代理
- 黑马程序员—高新技术:动态代理
- 黑马程序员_java高新技术之动态代理
- 黑马程序员---高新技术之动态代理类
- 黑马程序员----高新技术----之动态代理
- 黑马程序员-----高新技术-----动态代理详解
- 黑马程序员--Java高新技术代理类
- 黑马程序员 Java高新技术 代理总结
- 黑马程序员-JAVA 高新技术(代理)
- EXTJS4.0 页面间传值 监听事件的使用 值处理
- hdu-1495
- 音视频通讯开发的日志文件
- appfuse 访问很慢
- Missing Ranges
- 黑马程序员--java高新技术--动态代理
- 如何开始学习高伸缩性编程?
- 使用PBIS将Linux加入域
- hive0.14-insert、update、delete操作测试
- 不能改变天气, 但我们可以改变心情。
- 作业3
- HDU 1251
- SQL Server判断临时表是否存在
- this.text在firefox和IE9下的容错处理