黑马程序员_ 黑马程序员_基础加强第二天——代理
2014-04-19 18:39
288 查看
代理的概念与作用
为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等
与目标类具有相同接口,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码
代理架构:
![](https://img-blog.csdn.net/20140419184056765?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzY3Njc2NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
AOP(Aspect Oriented Programming)
解决交叉业务编程问题
问题: 安全 事务 日志
StudentService ------|----------|------------|-------------
CourseService ------|----------|------------|-------------
MiscService ------|----------|------------|-------------
解决:------------------------------------------------------切面
func1 func2 func3
{ { {
.... .... ......
} } }
------------------------------------------------------切面
使用代理技术正好可以解决这种问题,代理是实现AOP的核心和关键技术
动态代理技术
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中
JVM动态生成代理类及其分析:
例:生成Collection接口的代理类: class clazzProxy = Proxy.getProxyClass(Collection.getClassLoader().class, Collection.class);
它只有一个带参构造方法,带的参数是InvocationHandler
利用Proxy类的newProxyInstance一步创建代理类实例(利用匿名内部类创建InvocationHandler对象):
除了以上一步生成方法,也可利用clazzProxy获取构造方法再调用,生成实例。
问题:为什么动态类的实例对象的getClass()方法返回了正确结果而不是代理的目标类结果呢?
回答:调用调用代理对象的从Object类继承的hashCode, equals, 或toString这几个方法时,代理对象将调用请求转发给InvocationHandler对象,对于其他方法,则不转发调用请求。
JVM动态生成代理类原理以及框架:
原理图:
为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等
与目标类具有相同接口,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码
代理架构:
AOP(Aspect Oriented Programming)
解决交叉业务编程问题
问题: 安全 事务 日志
StudentService ------|----------|------------|-------------
CourseService ------|----------|------------|-------------
MiscService ------|----------|------------|-------------
解决:------------------------------------------------------切面
func1 func2 func3
{ { {
.... .... ......
} } }
------------------------------------------------------切面
使用代理技术正好可以解决这种问题,代理是实现AOP的核心和关键技术
动态代理技术
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中
JVM动态生成代理类及其分析:
例:生成Collection接口的代理类: class clazzProxy = Proxy.getProxyClass(Collection.getClassLoader().class, Collection.class);
它只有一个带参构造方法,带的参数是InvocationHandler
利用Proxy类的newProxyInstance一步创建代理类实例(利用匿名内部类创建InvocationHandler对象):
Collection col = (Collection) Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler(){ ArrayList target = new ArrayList(); //target要定义在invoke方法外面 @Override public 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(endTime - beginTime); return retVal; } });当调用col.add("abc");语句时,
@Override public Object invoke(Object proxy, Method method, Object[] args)中,proxy是指col对象,method即add方法,args即"abc"
除了以上一步生成方法,也可利用clazzProxy获取构造方法再调用,生成实例。
问题:为什么动态类的实例对象的getClass()方法返回了正确结果而不是代理的目标类结果呢?
回答:调用调用代理对象的从Object类继承的hashCode, equals, 或toString这几个方法时,代理对象将调用请求转发给InvocationHandler对象,对于其他方法,则不转发调用请求。
JVM动态生成代理类原理以及框架:
原理图:
相关文章推荐
- 黑马程序员_ 黑马程序员_基础加强第二天——类加载器
- 黑马程序员_Java基础加强第二天——Annotation
- 黑马程序员_Java基础加强第二天——内省/JavaBean
- 黑马程序员_基础加强第一天——Java反射机制
- 黑马程序员_基础加强第一天——JDK1.5新特性
- 黑马程序员_7k面试题_交通灯管理
- 黑马程序员_7k面试题_银行业务调度系统
- 懒加载未用就关闭sessio--n的异常---面试问的-org.hibernate.LazyInitializationException: could not initialize proxy -
- 黑马程序员-讲解Vector的特有取出方式Enumeration学习日记
- 前端开发面试题整理(JS篇)
- (转)2012年7月9 – 知名网页游戏公司 PHP高级工程师 最新面试题
- 【面试秘籍】PHP中级面试题
- (转)2012年7月12 – 腾讯公司 WEB高级应用开发工程师 最新面试题
- 面试经典(3)---链表倒数第k个节点
- 黑马程序员-List集合共性方法,ListIterator学习笔记
- 在无头节点的单链表里删除元素
- 面试经典(4)--链表逆序
- 黑马程序员-讲解Co a5df lletion共性方法学习日记
- 阿里面试总结