java动态代理_aop
(一)代理概述
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 动态代理,具体有如下四步骤:
- 通过实现 InvocationHandler 接口创建自己的调用处理器;
- 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
- 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
- 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
java动态代理_aop的更多相关文章
- Java 动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- Java动态代理全面分析
代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1 主题:规定代理类和真实对象共同对外暴露的接口: 2 代理类:专门代理真实对象的类: 3 ...
- JAVA动态代理模式(从现实生活角度理解代码原理)
所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...
- Java 动态代理作用是什么?
Java 动态代理作用是什么? 1 条评论 分享 默认排序按时间排序 19 个回答 133赞同反对,不会显示你的姓名 Intopass 程序员,近期沉迷于动漫ING 133 人赞同 ① 首先你 ...
- java动态代理原理
我们经常会用到Java的动态代理技术, 虽然会使用, 但是自己对其中的原理却不是很了解.比如代理对象是如何产生的, InvocationHandler的invoke方法是如何调用的?今天就来深究下Ja ...
- java 动态代理示例,带主要注释
Java proxy是基于反射,仅仅支持基于接口的动态代理. java 动态代理是一切架构的基础,必须了解. 废话少说,先上代码获得感性认识. 示例代码有主要注释. 接口: public interf ...
- java动态代理浅析
最近在公司看到了mybatis与spring整合中MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类. 于是想起了java的动态代理,然后就有了这篇文章 ...
- Java 动态代理
被代理的接口特点: 1. 不能有重复的接口,以避免动态代理类代码生成时的编译错误. 2. 这些接口对于类装载器必须可见,否则类装载器将无法链接它们,将会导致类定义失败. 3. 需被代理的所有非 pub ...
- [转]java动态代理(JDK和cglib)
转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理 ...
随机推荐
- go 删除数组元素
golang中对一个slice进行“slice”可以取片段得到一个新的slice,那么如何用简洁的代码删除slice中的一个元素呢? a := []int{0, 1, 2, 3, 4} //删除第i个 ...
- hydra 安装和使用
udo add-apt-repository ppa:pi-rho/security sudo apt-get update sudo apt-get install hydra hydra -l r ...
- Orchard模块开发全接触2:新建 ProductPart
一:创建 Part 1:项目引用 Orchard.Framework: 2:创建 Models 文件夹: 3:在 Models 文件夹下创建类 ProductPartRecord,如下: public ...
- Cannot create container for service peer1.org2.example.com: Conflict. 解决方案
I have a docker-compose.yaml file defining 5 services: orderer.example.com peer0.org1.example.com pe ...
- [转]Nginx 502 PHP LNMP 502 终极解决方案 完美解决502 用 upstream 和 fastcgi_next_upstream 可以极大缓解
转: http://xn--ghqyhzj.com/post-21537.html 本文针对LNMP的PHP 版本ver 5.3.6 or Higher,其它未测试过. 1. 使用不同端口或php-f ...
- git别名;git配置使用shell函数;git别名使用shell函数;git获取当前分支;git alias
获取当前分支 git symbolic-ref -q --short HEAD 2. 在git别名里使用shell函数,$1获取第一个参数的值,$2……$n依次类推,根据自己习惯需要定制 3. 提交r ...
- SharePoint 列表权限控制
一提到sharepoint 我相信权限控制一定会是一个很重要的话题,尤其是对列表的权限控制,创建.修改.查看权限.其实网上这方面的资料已经很多了,尤其是以下2篇文章,后来索性把CodeArt_Perm ...
- js面向对象之继承-原型继承
//animal 父类 超类 var Animal = function(name) { this.name = name; this.sayhello = function() { alert(&q ...
- MYSQL数据删除数据,物理空间没释放
当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTIMIZE TABLE 是指对表进行优化.如果已经删除了表的一大部分数据,或者如果已 ...
- RabbitMQ的应用场景以及基本原理介绍 【转】
http://blog.csdn.net/whoamiyang/article/details/54954780 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 背景 应用 ...