(一)代理概述

  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. spring4 quartz2 集群动态任务

    实现定时任务的执行,而且要求定时周期是不固定的.测试地址:http://sms.reyo.cn 生产环境:nginx+tomcat+quartz2.2.1+spring4.2.1 集群. 实现功能:可 ...

  2. linux syslog详解 转

    分三部分 一.syslog协议介绍 二.syslog函数 三.linux syslog配置   一.syslog协议介绍 1.介绍 在Unix类操作系统上,syslog广泛应用于系统日志.syslog ...

  3. 黑吃黑第一季/全集Banshee迅雷下载

    第一季 Banshee Season 1 (2013)看点:“Banshee”在爱尔兰盖尔语中被称为“bean sidhe”,意思是“拥有超能力的女人”.不过在鲍尔的新剧中,Banshee并不是指超自 ...

  4. mac下设置eclipse自动提示

    偏好设置  -> General -> Editors -> File Associations .xml ->  设置XML Editor为default Keys 中查找 ...

  5. 高速Android开发系列通信篇之EventBus

    概述及基本概念 **EventBus**是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间.组件与后台线程间的通信.比方请求网络,等网络返回时通过Hand ...

  6. SpringBoot 项目中使用velocity模板(转载)

    (不要使用这种模板了,spring boot最新版已经不支持了.使用FreeMarker吧:http://blog.csdn.net/clementad/article/details/5194262 ...

  7. [Android Security] jar文件转smali文件

    cp : https://blog.csdn.net/fengmm521/article/details/78446486 jar转smali文件一共要走两步,先将jar文件转为.dex文件 (dx工 ...

  8. how to use perf

    Since I did't see here anything about perf which is a relatively new tool for profiling the kernel a ...

  9. 置顶菜单demo

    一朋友需要置顶菜单的功能,给了个网站,让弄下来.看了下,就把样式及效果拔了下来.去掉了复杂的东西,只保留了其基本实现.有需要的朋友可以拿去用用. <style> #navigation{ ...

  10. Asp.Net验证控件浅析

    ASP.NET公有六种验证控件,分别如下: 控件名           功能描叙  RequiredFieldValidator(必须字段验证) 用于检查是否有输入值  CompareValidato ...