(一)代理概述

  1、问题:要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理等等,如何去做?

  解答:编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。

  2、代理原理图,如下:

3、代理的优点

  如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类、还是代理类,这样以后很容易切换。例如,想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能很容易,以后运行一段时间后,又想去掉系统功能也很容易。

代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。

在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,

通过使用这个类和接口就可以生成动态代理对象。

JDK提供的代理只能针对接口做代理。

(1)Proxy类中的方法创建动态代理类对象

他有一个方法:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

该方法用来产生一个object类型的代理对象

该对象并没有对应的.class文件,但在内存中有对应Class类型

实现 :

Object o =

java.lang.reflect.Proxy.

newProxyInstance(ClassLoader loader,Class[] classes, InvocationHandler handler);

参数说明:

ClassLoader loader            类加载器  用于把.class文件(字节码文件)加载到内存中     通过getClassLoader()方法获取

Class[] classes               目标接口的类型数组

InvocationHandler handler   接口调用处理器

(2)InvocationHandler接口

只有1个方法

public Object invoke(Object proxy, Method method, Object[] args)

当代理对象调用父接口中定义的方法时 执行的就是该方法


1.IGDG
package com.pers.proxy; public interface IGDG {
void doSomeThing();
}
2.TargetGDG
package com.pers.proxy; public class TargetGDG implements IGDG{ @Override
public void doSomeThing() {
System.out.println("我是目标类 正在忙着很多事情"); }
}
.ProxyGDG
package com.pers.proxy;
/*
* 代理类 与目标类TargetGDG具有相同的接口
* 代理类的每个方法调用目标类的相同方法 并在调用方法的时候加上系统功能的代码
*/
public class ProxyGDG implements IGDG { public void doSomeThing() {
addLogging();
new TargetGDG().doSomeThing();//目标类的实现方法
doException();
}
/*
* 我要横切加入到目标类中的系统方法 这样的话就不用往每个类中都去加
*/
public void addLogging(){
System.out.println("为每个类都加上日志");
}
public void doException(){
System.out.println("为每个类都处理异常");
}
//..........省略其他系统功能的代码
}
4.
ProxyDemo
package com.pers.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class ProxyDemo { public static void main(String[] args) {
// TODO Auto-generated method stub
//1.声明代理类对象
final Object obj = new ProxyGDG();
System.out.println("声明被代理的对象是:"+obj.getClass());//com.pers.proxy.ProxyGDG
//使用proxy类创建IGDG接口的子类
Object proxyObject = Proxy.newProxyInstance(
ProxyDemo.class.getClassLoader(),
new Class[]{IGDG.class},
new InvocationHandler(){
@Override
public Object invoke(Object proxyObject, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("你正在执行的方法名是:"+method.getName());
return method.invoke(obj,args);
}
});
//将子类强转为IGDG
IGDG iGDG = (IGDG)proxyObject;
iGDG.doSomeThing();//iGDG是代理
System.out.println("声明被代理的对象是:"+iGDG.getClass());//$Proxy0
} }

动态生成的类的内部代码分析

实现Collection接口的动态类中的各个方法的代码又是怎样的呢? InvocationHandler接口中定义的invoke方法接收的三个参数又是什么意思?

InvocationHandler接口中定义的invoke方法接收的三个参数意义,如下图说明:

说明:客户端调用了代理对象objProxy,调用了代理对象的add()方法,为该方法传递了字符串参数"abc"。

通过分析代码可以看出Java 动态代理,具体有如下四步骤:
  1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
  2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
  3. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

java动态代理_aop的更多相关文章

  1. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  2. Java动态代理全面分析

    代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1  主题:规定代理类和真实对象共同对外暴露的接口: 2  代理类:专门代理真实对象的类: 3 ...

  3. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  4. Java 动态代理作用是什么?

    Java 动态代理作用是什么?   1 条评论 分享   默认排序按时间排序 19 个回答 133赞同反对,不会显示你的姓名 Intopass 程序员,近期沉迷于动漫ING 133 人赞同 ① 首先你 ...

  5. java动态代理原理

    我们经常会用到Java的动态代理技术, 虽然会使用, 但是自己对其中的原理却不是很了解.比如代理对象是如何产生的, InvocationHandler的invoke方法是如何调用的?今天就来深究下Ja ...

  6. java 动态代理示例,带主要注释

    Java proxy是基于反射,仅仅支持基于接口的动态代理. java 动态代理是一切架构的基础,必须了解. 废话少说,先上代码获得感性认识. 示例代码有主要注释. 接口: public interf ...

  7. java动态代理浅析

    最近在公司看到了mybatis与spring整合中MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类. 于是想起了java的动态代理,然后就有了这篇文章 ...

  8. Java 动态代理

    被代理的接口特点: 1. 不能有重复的接口,以避免动态代理类代码生成时的编译错误. 2. 这些接口对于类装载器必须可见,否则类装载器将无法链接它们,将会导致类定义失败. 3. 需被代理的所有非 pub ...

  9. [转]java动态代理(JDK和cglib)

    转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理 ...

随机推荐

  1. .NET:使用 XPATH 读取有 xmlns 属性的 XML 文档出现的问题

    问题 xml <sqlMap namespace="WHTR.Dao.Accounts" xmlns="http://ibatis.apache.org/mappi ...

  2. 一篇linux的通讯文章

    今年的linux内核开发大会上,google的开发人员也上台做了名为“how google use linux”的演讲.我斗胆翻译注解一番――括号内为注解,欢迎读者斧正. 原文链接参见:http:// ...

  3. MySQL递归查询树状表的子节点、父节点具体实现

    mysql版本(5.5.6等等)尚未支持循环递归查询,和sqlserver.oracle相比,mysql难于在树状表中层层遍历的子节点.本程序重点参考了下面的资料,写了两个sql存储过程,子节点查询算 ...

  4. 关于 java,nio,bufferedreader,bytebuffer

    有没有一种方法来读取的ByteBuffer有一个BufferedReader,而无需将其转换为String优先?我想读通过一个相当大的 ByteBuffer作为文本行和我想避免它写入磁盘性能方面的原因 ...

  5. Wireshark基本用法 && 过滤规则 && 协议详解

    基本使用: https://www.cnblogs.com/dragonir/p/6219541.html 协议解析: https://www.jianshu.com/p/a384b8e32b67 ( ...

  6. SVN更新的问题

    更新的时候一直遇到"Base checksum mismatch on"或者"Checksum mismatch while updating",其它文件可以提 ...

  7. Android NDK:Aborting..Stop的处理方法

    在eclipse中配置cocos2d-x的android环境时,遇到这样的错误提示 网上搜索了一下,说是在NDK_MODULE_PATH环境变量下未找到所需要的Android.mk文件,后来仔细研究了 ...

  8. Activity间用Intent、Bundle、onActivityResult进行传值

    其实Activity间的传值就是通过Bundle,intent中也是自动生成了Bundle来传值,里面还有个onActivityResult()方法也可以传送数值. 如果一个Activity是由sta ...

  9. hdu 1038 Biker&#39;s Trip Odometer(水题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=1038 Biker's Trip Odometer Time Limit: 2000/1000 MS ...

  10. Maven中的库(repository)详解

    Maven中的库(repository)是构件(artifact)的集合.构件以一定的布局存储在库中. 本地仓库 vs. 远程仓库 运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获 ...