(一)代理概述

  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. 关于tomcat和sessionCookieName和SESSION_PARAMETER_NAME以及disableURLRewriting参数原理和使用

    关于tomcat和sessionCookieName和SESSION_PARAMETER_NAME以及disableURLRewriting参数 关于session和cookie参考: http:// ...

  2. url空格转码的问题

    上知乎在搜索框里输入"1-n 随机数"(中间有空格,然后会看到了这个界面)   最开始我使用的是chrome,发现有脚本报错了,以为是服务器维护了,但再一想,不对啊,刚刚明明是好的 ...

  3. Android组件化之终极方案

    Android组件化项目地址:Android组件化项目AndroidModulePattern Fragment或View如何支持组件化 如何管理组件 Fragment或View如何支持组件化 距离 ...

  4. MARQUEE 字符滚动条效果

    <MARQUEE scrolldelay =“100” direction=“up " > 滚动文字或图像 </MARQUEE> 说明: – scrolldelay: ...

  5. 中文代码之Spring Boot集成H2内存数据库

    续前文: 中文代码之Spring Boot添加基本日志, 源码库地址相同. 鉴于此项目中的数据总量不大(即使万条词条也在1MB之内), 当前选择轻量级而且配置简单易于部署的H2内存数据库比较合理. 此 ...

  6. 基于DPI(深度报文解析)的应用识别

    一.概述 1.DPI(Deep packet inspection,深度报文解析) 所谓“深度”是和普通的报文分析层次相比较而言的,“普通报文检测”仅分析IP包4 层以下的内容,包括源地址.目的地址. ...

  7. go语言之进阶篇JSON处理

    一.JSON处理 JSON (JavaScript Object Notation)是一种比XML更轻量级的数据交换格式,在易于人们阅读和编写的同时,也易于程序解析和生成.尽管JSON是JavaScr ...

  8. 解剖android中的闹钟app 一

    首先,看一看android市场上有哪些主流的闹钟app了,我们来进行一个简单的评测: 一.正点闹钟 这是一款源自金山技术的闹钟app,其主力创始团队都是来自于金山,其装机量,下载量都是排名第一.老样子 ...

  9. light oj 1007 Mathematically Hard (欧拉函数)

    题目地址:light oj 1007 第一发欧拉函数. 欧拉函数重要性质: 设a为N的质因数.若(N % a == 0 && (N / a) % a == 0) 则有E(N)=E(N ...

  10. Android -- 状态栏高度

    干货 Class<?> c = null; Object obj = null; Field field = null; int x = 0, sbar = 0; try { c = Cl ...