zoukankan      html  css  js  c++  java
  • 动态代理

    1.代理模式

    代理模式作用:

    屏蔽真实行为的访问,让程序更加安全。
    可以对真实行为的调用进行控制。

    通过一个案例:来说明代理的实现以及代理的作用

    代理类和被代理类实现的同一个接口

    1. package cn.itcast.proxy;
    2. //风流的女人
    3. publicinterfaceKindWoman{
    4. publicvoid throwEye();
    5. publicvoid doSomething();
    6. }

    pjl作为被代理类,实现接口

    1. //潘金莲 ---被代理
    2. publicclassPjlimplementsKindWoman{
    3. publicvoid throwEye(){
    4. System.out.println("潘金莲抛媚眼");
    5. }
    6. publicvoid doSomething(){
    7. System.out.println("潘金莲。。。。。。。。");
    8. }
    9. }

    而代理类需要实现接口,同时有一个构造方法,来接受被代理类的对象

    1. //代理
    2. publicclassWpimplementsKindWoman{
    3. privateKindWoman woman;
    4. publicWp(KindWoman woman){
    5. this.woman = woman;
    6. }
    7. publicvoid throwEye(){
    8. //在这里做操作,可以控制是否调用真实行为。
    9. woman.throwEye();
    10. //在这个位置,可以在真实行为调用完成后,在做操作。
    11. }
    12. publicvoid doSomething(){
    13. woman.doSomething();
    14. }
    15. }

    测试的时候,我们执行的是wp,但是调用的是pjl

    1. publicclassXmq{
    2. publicstaticvoid main(String[] args){
    3. KindWoman woman =newJs();
    4. Wp wp =newWp(woman);
    5. wp.throwEye();//真实执行的是潘金莲,但是我们看不到,所以屏蔽了真实行为。
    6. }
    7. }

    代理模式实现:

    1.代理类与被代理类要实现同一个接口.
    2.在代理类中持有被代理对象.
    3.在代理类中调用被代理的行为。

    AOP:面向方面的编程。
    AOP的底层实现就是通过动态代理来做到的。

    2.动态代理

    它就是在代理模式基础上发展的,它不在是对单一的类型进行代理,
    而是可以对任意的一个实现了接口的类的对象做代理。

    3.动态代理实现

    有两种方式:

    1.通过jdk中提供的Proxy类来实现
    这种方式要求,被代理类必须实现接口。
    简单说,只能为接口做代理.
    2.通过cglib来实现。
    它不要求,实现接口。主要是通过修改字节码实现的。

    4 Proxy代码实现:

    Proxy类中有一个方法newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h);

    参数:
    (1)loader:
    要求,传递的是被代理类的类加载器ClassLoader.

    类加载器怎样获取:
    得到其Class对象。在Class类中提供一个方法 getClassLoader();

    (2)interfaces:
    要求:得到被代理对象所实现的接口的所有Class对象。
    怎样获取所有实现接口的Class对象?
    得到其Class对象,在Class类中提供一个方法 getInterfaces();
    它返回的是Class[],就代表所实现接口的所有Class对象。

    (3)h:
    它的类型是InvocationHandler,这是一个接口。
    InvocationHandler 是代理实例的调用处理程序 实现的接口。

    InvocationHandler接口中有一个方法invoke;
    // 参数 proxy就是代理对象
    // 参数method就是调用方法
    // 参数args就是调用的方法的参数
    // 返回值,就是真实行为执行后返回的结果,会传递给代理对象调用的方法.
    public Object invoke(Object proxy, Method method, Object[] args);

    代码

    注意下面代码Proxy.newProxyInstance返回的对象类型应该是接口,此时要注意代理和被代理对象之间是一个兄弟的关系,也就是说他们的父辈是接口,所以一个兄弟不能等于另一个兄弟,而应该等于它的接口,是接口产生的它,而如何去代理你的兄弟呢,在newProxyInstance参数中有需要传递被代理对象的类加载器,还有接口等,这些其实都是说明这个代理类是在那个接口下实现的类,也就是说明他是接口的儿子(被代理类的兄弟),接着要说明我代理哪一个兄弟,需要在InvocationHandler(接口)这个实现类中去说明。
    InvocationHandler这是一个接口,我们才用匿名内部类(用的时候直接穿件了他的对象),他里面有三个参数,第一个就说明了我们需要去代理哪一个兄弟,剩下的 是代理哪一个方法和方法中的参数,具体返回时method.invoke,需要两个参数第一个是具体哪个兄弟。


    我们分析一下到底是怎么代理的,当sproxy.say执行的时候,会实例化InvocationHandler对象,并且执行其中的invoke方法,那么此时第二个参数method就是调用的方法say,第三个参数args就是“james",然后会返回被代理对象执行该方法的结果,得到message,所以代理对象执行的时候是要走invoke方法内的东西,这也就实现了过滤和安全性考虑。上面相同颜色代表同一个东西

    1. publicstaticvoid main(String[] args){
    2. finalKindWoman woman =newPjl();
    3. // 做一个Pjl的代理.
    4. KindWoman proxy =(KindWoman)Proxy.newProxyInstance(woman.getClass()
    5. .getClassLoader(), woman.getClass().getInterfaces(),
    6. newInvocationHandler(){
    7. publicObject invoke(Object proxy,Method method,
    8. Object[] args)throwsThrowable{
    9. return method.invoke(woman, args);//woman.方法名(参数)
    10. }
    11. });
    12. }





  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/oneNightStand/p/6509812.html
Copyright © 2011-2022 走看看