java之Spring(AOP)前奏-动态代理设计模式(上)

我们常常会遇到这样的事,项目经理让你为一个功能类再加一个功能A,然后你加班为这个类加上了功能A;

过了两天又来了新需求,再在A功能后面加上一个新功能B,你加班写好了这个功能B,加在了A后面;又过

了几天天,项目经理说这两个新加的功能顺序需要调换一下,然后你找到一个礼拜之前的写的源代码,看了

一遍想起来当时是怎么实现的了,这部分是功能A,那部分是功能B,然后巴拉巴拉换了顺序。看到这是不是

觉得很烦,动不动就要在源码上加新功能,完了又要在源码上换新功能的顺序,那么一大坨源码,还好是自

己写的源码,理解起来很快,操作起来也很快,万一是别人的源码,别人的编程习惯可能和自己的不一样,

看他的源码,又要多花点时间,真是卷铺盖走人的心都有了。

这个时候,我们就可以用代理来为源码有序地添加新功能。

1.定义一个接口

public interface InterfaceDo {
    public void dosomething();
}

2.定义原始功能类

public class Persontodo implements InterfaceDo {
    public void dosomething() {
        System.out.println("要干什么呢--------");
    }
}

我们可以看到,这个类实现了之前的接口, 但是只做一件事:思考人生!

3.定义额外功能类,并实现对原始功能的调用

public class Impeat implements InterfaceDo {
    private InterfaceDo todo;
    public Impeat(InterfaceDo todo) {
        super();
        this.todo = todo;
    }
    public void dosomething() {
        todo.dosomething();
        System.out.println("我要吃饭了啊--------");
    }
}

我们看到这个类引入了一个成员变量,类型为InterfaceDo(接口)类型,

构造函数实现为成员变量赋值,那么当我们实例化这个类的时候,它内部的成员变量是指向传入的参数对象的实例的。

Persontodo a = new Persontodo();

Impeat b  = new Impeat(a);

那么,b.dosomething()这个方法实现的功能是:先执行实例化时候传进来的参数todo的todo.dosomething()方法,然后

再执行语句System.out.println("我要吃饭了啊------------");

在上面的例子由于传进来的参数是a,那么b.dosomething()就同等于以下两步操作:

①a.dosomething();

②System.out..println("我要吃饭了啊------------");

结果控制台打印输出:

要干什么呢--------

我要吃饭了啊---------

弄懂之后我们再来新建个Impeat这样的类,同样是实现InterfaceDo接口

public class Impgame implements InterfaceDo {
    private InterfaceDo todo;
    public Impgame(InterfaceDo todo) {
        super();
        this.todo = todo;
    }
    public void dosomething() {
        System.out.println("我要玩游戏了啊--------");
        todo.dosomething();
    }
}

上面接口实现类的含参构造函数的参数是InterfaceDo(接口)类型,所以参数可以是该接口所有实现类的实例化对象。

4.多态的运用

public class Testperson {
    public static void main(String[] args) {
        Persontodo a = new Persontodo();
        Impeat c = new Impeat(a);
        Impgame d = new Impgame(c);
        Impsleep b = new Impsleep(d);
        b.dosomething();
    }
}

我们可以看到这个测试类,将原始功能类的实例化对象作为参数传给Impeat的含参构造器,然后将Impeat的实例化对象

作为参数传给Impgame的含参构造器,再将Impgame的实例化对象作为参数传给Impsleep的含参构造器,最后调用了

Impgame的实例化对象的dosomething()方法。

那么,实际上这个方法是:

先调用参数的dosomething()方法然后打印一条语句,而参数的dosomething()方法也是

先调用参数的dosomething()方法然后打印一条语句,如此循环,可以用一张图表示。

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

每个框都是一个类,当然新增功能顺序可以自由选择,你也可以先实现功能2在实现1。

如此一来每个除原始功能类之外的功能类,都是具备往其他功能类上添加功能的能力的。

由于上面所有的类都是实现InterfaceDo接口的,那么可以将上面的代码改写一下:

public class Testperson {
    public static void main(String[] args) {
        InterfaceDo a = new Persontodo();
        InterfaceDo c = new Impeat(a);
        InterfaceDo d = new Impgame(c);
        InterfaceDo b = new Impsleep(d);
        b.dosomething();
    }
}

不难看出,这就是引用多态,接口的引用指向实现类的对象。

c在a的功能基础上添加了功能;

d在c的功能基础上添加了功能;

b在d的功能基础上添加了功能。

这就实现了静态代理。

时间: 2024-10-11 17:17:00

java之Spring(AOP)前奏-动态代理设计模式(上)的相关文章

Spring AOP 前奏--动态代理

用spring aop实现动态代理的例子

下面由我来给大家展示用spring aop实现动态代理的例子(电脑打印) 下面就看一下具体的代码: 先定义一个打印机的接口 1 package aop007_ComPrint; 2 3 public interface Print { 4 5 public void ColorPrint(); //彩色打印 6 public void WhitePrint(); //黑白打印 7 } 然后定义两个实现类,分别实现彩色打印和黑白打印 1 package aop007_ComPrint; 2 3 p

Spring AOP --JDK动态代理方式

我们知道Spring是通过JDK或者CGLib实现动态代理的,今天我们讨论一下JDK实现动态代理的原理. 一.简述 Spring在解析Bean的定义之后会将Bean的定义生成一个BeanDefinition对象并且由BeanDefinitionHolder对象持有.在这个过程中,如果Bean需要被通知切入,BeanDefinition会被重新转换成一个proxyDefinition(其实也是一个BeanDefinition对象,只不过描述的是一个ProxyFactoryBean).ProxyFa

Spring AOP JDK动态代理与CGLib动态代理区别

静态代理与动态代理 静态代理 代理模式 (1)代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. (2)静态代理由 业务实现类.业务代理类 两部分组成.业务实现类 负责实现主要的业务方法,业务代理类负责对调用的业务方法作拦截.过滤.预处理,主要是在方法中首先进行预处理动作,然后调用业务实现类的方法 例子 /** * 定义一个账户接口 * @author Administrator */ public interface Count { //

Spring AOP之 动态代理实例

1.项目结构图如下3.3.3.1: 图3.3.3.1 2.IUserServ接口代码与UserServImpl实现类代码和上述代码相同 3.LogHandler类代码 public class LogHandler implements InvocationHandler { //目标对象 private Object targetObject; /** * 创建动态代理类 * @return object(代理类) */ public Object createProxy(Object tar

java架构解密——AOP之动态代理实现

在上篇博客中,我们在宏观上介绍了AOP的底层实现,具体见博客java架构解密--Spring框架的AOP,在博客中,我们讲述了Aop的一些设计上的思路,今天,咱们就具体的实现,和大家一起探讨,看看AOP是怎么一步一步走到今天,而且有些图,也要做些纠正! 一,代码演变 前提:最初要实现的功能(打招呼) 代码: 接口: <span style="font-size:18px;">public interface Greeting { void sayHello(String n

Spring——AOP(动态代理)

以例子说明: 一.创建两个接口,并创建各自的实现类,实现类在XML文件中进行配置,并在测试类中取得各实现类的实例 二.创建代理类,实现InvocationHandler接口 (1)声明实际代理的对象 1 private Object obj;  (2)创建绑定的方法,通过传入的实际代理对象创建对应的代理对象 1 /** 2 * @param obj 3 * @return 代理对象 4 */ 5 public Object bind(Object obj) 6 { 7 this.obj = ob

Java的反射机制和动态代理

介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原生实现AOP中 的方法拦截功能.正如英文单词reflection的含义一样,使用反射API的时候就好像在看一个Java类在水中的倒影一样.知道了Java类的内部 结构之后,就可以与它进行交互,包括创建新的对象和调用对象中的方法等.这种交互方式与直接在源代码中使用的效果是相同的,但是又额外提供了运行时

AOP jdk动态代理

一: jdk动态代理是Spring AOP默认的代理方法.要求 被代理类要实现接口,只有接口里的方法才能被代理,主要步骤是先创建接口,接口里创建要被代理的方法,然后定义一个实现类实现该接口,接着将被代理对象注入到一个中间对象,中间对象实现InvocationHandler接口,实现该接口可以在 被代理对象调用它的方法前后插入一些代码.Proxy.newProxyInstance()能利用中间对象来生产代理对象. 二: (1)创建接口: package net.wang.aop; /** * 被代