1.程序中的代理

为具有相同接口的目标类的各个方法,添加一些系统功能,如日志,异常处理,计算方法运行的

时间,事务管理等等,都可以交给另一个类去实现这些功能,该类称为代理类。

注意:为了让代理类共享目标类中的各个方法,可以让代理类实现和目标类相同的接口。

  public class AProxy {
//AProxy类为A的代理类,可以计算sayHi方法的运行时间
public void getTime()
{
//方法开始前时间
new A().sayHi();
//方法结束后时间
}
}
class A
{
void sayHi()
{
System.out.println("hi,everyone!");
}
}

2.代理架构图

它采用工厂模式和配置文件的方式进行管理,这样就不需要修改客户端程序,通过

配置文件指定使用目标类,还是代理类。这样做添加/去掉系统功能变得简单。

当我们需要测试系统的性能时,可以使用代理类,客户要使用时可以使用目标类

3.AOP(Aspect oriented program)

交叉业务:要处理不同层面的业务(service),称为交叉业务,如安全,事务,日志等。

安全       事务         日志
    StudentService  ------|----------|------------|-------------
    CourseService   ------|----------|------------|-------------
    MiscService       ------|----------|------------|-------------

用具体的程序代码描述交叉业务:
     method1         method2          method3
     {                      {                       {
       ------------------------------------------------------切面
          ....            ....              ......
       ------------------------------------------------------切面
      }                       }                       }

面向方面的编程(简称AOP),AOP的目标就是要使交叉业务模块化。

可以采用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果是一样的,如下所示:
       ------------------------------------------------------切面
       func1         func2            func3
        {             {                {
          ....            ....              ......
         }             }                }
      ------------------------------------------------------切面

这里就是使用代理技术解决这种问题,代理是实现AOP功能的核心和关键技术。
4.动态代理技术

  • 要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!
  • JVM提供了动态代理类(Proxy)。即可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类。这里是仅指具有接口的代理类和目标类。
  • 对于没有接口的目标类,CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。

代理方法中的有如下四个位置加上系统功能代码:

1.在调用目标方法之前
     2.在调用目标方法之后
     3.在调用目标方法前后
     4.在处理目标方法异常的catch块中

class proxy{
void sayHello(){
………//1
try{
target.sayHello();
}catch(Exception e){
………//4
}
…………//2
}
}

5.Proxy(代理类)

      |-java.lang.reflect.Proxy

Proxy提供了创建动态代理类和实例的静态方法,它也是这些创建出来类的超(父)类。

构造方法:

protected  Proxy(InvocationHandler  h);//使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy 实例

成员方法:

static Class<?> getProxyClass(ClassLoader loader,Class<?> interfaces);//创建一个具有接口的动态代理类。

static Object newProxyInstance (ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);//返回一个代理类实例对象

创建代理类及其实例对象:

法一:先创建代理类,再用代理类的构造方法创建实例对象

public static void main(String[] args) {
// 获得一个集合接口的代理类,为其指定接口和类加载器
//通常loader,interface是一样的字节码产生的
Class clazzProxy1=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
//创建一个代理类实例
//注意:clazzProxy1.newInstance()调用的是它的无参构造方法创建实例,但是它没有无参的构造方法
//通过有参构造方法创建实例
Constructor ct=clazzProxy1.getConstructor(InvocationHandler.class);
class MyinvocationHandler implements InvocationHandler
{
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
Collection proxy1=(Collection) ct.newInstance(new MyinvocationHandler());
}}

法二:用new方法直接创建代理类实例对象

Object target=new Object ();
Object proxy1=Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler(){ @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}); Class<?> []cs={Collection.class};
Collection proxy3=(Collection)Proxy.newProxyInstance
(Collection.class.getClassLoader(),
cs,new MyinvocationHandler());
Collection proxy4=(Collection)Proxy.newProxyInstance
(Collection.class.getClassLoader(),
new Class[] {Collection.class},
new MyinvocationHandler());

6.InvocationHandler(接口)

成员方法:

Object invoke(Object proxy, Method method, Object[] args);//在代理实例上处理方法调用并返回结果。

事实上,Proxy代理类对象调用(该接口上的)方法时,其实是去调用了handler的

invoke方法。对于不是该接口上的方法,如getClass(),则调用它本身的,不用委托handler去调用invoke方法。

7.代理类的模式

以面向对象的思想处理AOP(面向方面编程)的业务,即在实现代理的系统功能时,将目标类对象和接口(该接口通常以实现接口某个类的方式传入,实现接口里的方法(系统功能)的类)作为参数传入一个要实现系统功能的方法中。

        ArrayList al=new ArrayList();
Collection proxy4=(Collection)getProxy(al,new Myadvice());
proxy4.add("hq");
//以下是封装了实现代理功能的一个方法
//参数:目标类对象,和接口(实现代理功能的类,类里有实现功能的方法),该接口通常以实现接口某个类的方式传入。
private static Object getProxy(final Object target,final interfaceAdvice advice) {
Object proxy=Proxy.newProxyInstance
(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler(){ @Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
advice.beforeMethod(method);
Object obj=method.invoke(target, args);
advice.afterMethod(method);
return obj;
}
});
return proxy;
}

8.实现AOP功能的封装与配置

工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例 对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则,返回该类实例对象的 getProxy方法返回的对象。
BeanFactory的构造方法接收代表配置文件的输入流对象,配置文件格式如下:
    #xxx=java.util.ArrayList
    xxx=cn.itcast.ProxyFactoryBean
    xxx.target=java.util.ArrayList
    xxx.advice=cn.itcast.MyAdvice
ProxyFacotryBean充当封装生成动态代理的工厂,需要为工厂类提供哪些配置参数信息?
目标:target
通知:advice
编写客户端应用:
编写实现Advice接口的类和在配置文件中进行配置
调用BeanFactory获取对象。

摘自:

http://www.cnblogs.com/beyondbycyx/p/4314536.html

Java-动态代理技术的更多相关文章

  1. java动态代理技术

    主要用来做方法的增强.让你能够在不改动源代码的情况下,增强一些方法,在方法运行前后做不论什么你想做的事情(甚至根本不去运行这种方法).由于在InvocationHandler的invoke方法中,你能 ...

  2. 代理模式 & Java原生动态代理技术 & CGLib动态代理技术

    第一部分.代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...

  3. Java中动态代理技术生成的类与原始类的区别 (转)

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

  4. Java中动态代理技术生成的类与原始类的区别

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

  5. Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架

    类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...

  6. Java中动态代理技术生成的类与原始类的区别 (good)

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

  7. java动态代理原理

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

  8. 【转载】Java 动态代理

    Java 动态代理 本文为 Android 开源项目源码解析 公共技术点中的 动态代理 部分项目地址:Jave Proxy,分析的版本:openjdk 1.6,Demo 地址:Proxy Demo分析 ...

  9. Java动态代理简单应用

    概念 代理模式是基本的设计模式之一,它是开发者为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象.这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色. Java动态代理比 ...

  10. Spring AOP 和 动态代理技术

    AOP 是什么东西 首先来说 AOP 并不是 Spring 框架的核心技术之一,AOP 全称 Aspect Orient Programming,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...

随机推荐

  1. eclipse自动添加javadoc注释

    参考文档: https://jingyan.baidu.com/article/36d6ed1f70ea9c1bce488350.html https://www.cnblogs.com/yangji ...

  2. HDU 3407.Zjnu Stadium 加权并查集

    Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  3. 从1~N中任选出三个数,最小公倍数最大

    已知一个正整数N,问从1~N中任选出三个数,它们的最小公倍数最大可以为多少. 当n为奇数:n.n-1.n-2这是三个最大数,并且它们两两互质.因为连续的奇.偶.奇,互质.连续的两个数互质是因为它们的公 ...

  4. Eclipse快捷键系列

    查看Eclipse自定义的快捷键或者自己定义快捷键的方式 Window --> preference --> general --> Keys 在光标所在行之后插入一行,省去了将光标 ...

  5. lodash 中常用的方法

    odash是js集Array/Object/String/Function的Util于一身. lodash打包了Array/Object/String/Function里一些Api,好处是连ES6的也 ...

  6. Java页面中EL的${}与<%= request.getParameter%>有什么区别? el 取不到值

    ${requestScope}操作的是request的作用域,相当于request.getAttribute();不过EL比这个更智能些,它不用强制类型转换就可以拿到了真实对象的值.request.g ...

  7. Vuejs2.0之异步跨域请求

    Vuejs由1.0更新到了2.0版本.HTTP请求官方也从推荐使用Vue-Resoure变为了axios.接下来我们来简单地用axios进行一下异步请求.(阅读本文作者默认读者具有使用npm命令的能力 ...

  8. mybatis学习五 log4j

    1.  log4j(log for java)由 apache 推出的开源免费日志处理的类库.2. 为什么需要日志: 2.1 在项目中编写 System.out.println();输出到控制台,当项 ...

  9. HTML-入门篇day01

    HTML-入门篇day01 1.web     C/S:Client Server    客户端 服务器    QQ,...    B/S:Browser Server    浏览器 服务器 PC机: ...

  10. 2019.01.19 codeforces896C.Willem, Chtholly and Seniorious(ODT)

    传送门 ODTODTODT出处(万恶之源) 题目简述: 区间赋值 区间加 区间所有数k次方和 区间第k小 思路:直接上ODTODTODT. 不会的点这里 代码: #include<bits/st ...