黑马程序员----动态代理
来源:互联网 发布:网络流行语大全网站 编辑:程序博客网 时间:2024/06/05 20:27
------- android培训、java培训、期待与您交流! ----------
什么是代理:要为已存在的多个具有相同接口的目标类的方法增加一些系统功能。比如:事物处理,异常处理,日志等。
也就是业务交叉。面向切面编程AOP(Aspect Oriented program)
什么是动态代理:JVM可以再运行期间动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
两中实现方式:
JVM生成动态类必须实现一个或多个接口,所以jvm生成的动态类只能用作具有相同接口的目标类的代理。
什么是代理:要为已存在的多个具有相同接口的目标类的方法增加一些系统功能。比如:事物处理,异常处理,日志等。
也就是业务交叉。面向切面编程AOP(Aspect Oriented program)
什么是动态代理:JVM可以再运行期间动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
两中实现方式:
JVM生成动态类必须实现一个或多个接口,所以jvm生成的动态类只能用作具有相同接口的目标类的代理。
怎么让一个没有实现接口的类生成动态代理类呢?可以使用CGLIB库。他可以动态的生成一个类的子类,一个类的子类也可以用作该类代理类。
动态代理工作原理图:
代码实现:分析JVM生成动态类,以及获取生成动态类的方法信息列表
package Proxy;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 ProxyDemo {/** * @分析JVM生成动态类,以及获取生成动态类的方法信息列表 */public static void main(String[] args) throws Exception{//通过反射获取jvm生成动态的字节码文件//参数说明: 第一个参数classLoader:一般使用使用接口的类加载器,第二个参数:该动态类需要实现的接口Class clazzProxy1=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);System.out.println(clazzProxy1.getName());//获取构造方法Constructor[] constructors=clazzProxy1.getConstructors();for(Constructor constructor: constructors){System.out.println(constructor);//这个打印出public $Proxy0(java.lang.reflect.InvocationHandler) 。说明只有一个构造方法。}System.out.println("begin new instance-------");Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class);Collection proxy1=(Collection) constructor.newInstance(new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn null;}});System.out.println(proxy1); //proxy1.size(); size()方法有返回值。报空指针错误System.out.println("第二种创建动态实例对象方法:");Collection proxy2=(Collection) Proxy.newProxyInstance(Collection.class.getClassLoader(),new Class[]{Collection.class},new InvocationHandler() {ArrayList traget=new ArrayList();@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {long beginTime=System.currentTimeMillis(); Object retVal=method.invoke(traget, args); long endTime=System.currentTimeMillis()-beginTime; System.out.println(method.getName()+"耗时"+(endTime-beginTime));return retVal;}}); proxy2.add("zd"); proxy2.add("lx"); proxy2.add("wcb"); System.out.println(proxy2.size());}}面向切面实现,把代理类封装使用,可以插入日志信息等:
package Proxy;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 ProxyDemo2 {public static void main(String[] args) { Collection traget=new ArrayList();Collection proxy2 = (Collection) getProxy(traget,new AdvicceService()); proxy2.add("zd"); proxy2.add("lx"); proxy2.add("wcb"); System.out.println("---------"+proxy2.size());} /** * 此方法可以一直使用,动态代理类 * @param traget * @param advice * @return proxy2 */private static Object getProxy(final Object traget,final Advice advice) {Object proxy2= Proxy.newProxyInstance(traget.getClass().getClassLoader(), //用什么接口就用它的类加载器traget.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable { advice.beforMethod(method); Object retVal=method.invoke(traget, args); advice.afterMethod(method);return retVal;}});return proxy2;}}接口:
package Proxy;import java.lang.reflect.Method;public interface Advice { void beforMethod(Method method); void afterMethod(Method method);}接口实现类:
package Proxy;import java.lang.reflect.Method;public class AdvicceService implements Advice {private long beginTime=0;@Overridepublic void beforMethod(Method method) {beginTime=System.currentTimeMillis();}@Overridepublic void afterMethod(Method method) { long endTime=System.currentTimeMillis()-beginTime; System.out.println(method.getName()+"耗时"+(endTime-beginTime));}}------- android培训、java培训、期待与您交流! ----------
0 0
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员--动态代理
- 黑马程序员--动态代理
- 黑马程序员-动态代理
- 黑马程序员---------动态代理
- 黑马程序员-动态代理
- 黑马程序员-动态代理
- 黑马程序员-动态代理
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员------动态代理
- 黑马程序员 动态代理
- 黑马程序员----动态代理
- 黑马程序员-----动态代理
- 黑马程序员----动态代理
- PHP: Yii 或 Gii 无法登陆问题解决
- javascript中的Dom对象(续)
- db2删除default约束
- springMVC 多 dispatcherServlet 配置
- Tomcat升级到6.0遇到的双引号改单引号问题
- 黑马程序员----动态代理
- Android 自动检测版本升级
- JUnit中的测试套件和参数化测试【转】
- vc6.0对dynamic_cast的支持
- Web开发流程参考
- iOS7CollectionView有空白头部的解决方案
- iso开发——设置文档不支持ARC
- java 与 R rjava
- 贪心算法