OOP+AOP=高效+高效

来源:互联网 发布:php开发工程师简历 编辑:程序博客网 时间:2024/05/21 06:58
始于按部就班的行动,停于消化吸收的理论,驶向应用创新的实践!(任何一项技术、思想的出现,以及经过漫长时间的进化洗礼,总是有其精妙绝伦之处,都值得我们细细品味、慢慢研磨)

问题始于实际:先让我们看一个实际的例子:

例如:一个办公室的多个人合同去完成一个项目,由你去支配这n个人去工作,n个人分别完成n个任务;

oop:你需要关注的是给每个人分配什么样的任务,比如第一个人A任务,第二个人B任务等等;而到了半途,n个人都需要喝水、吃饭等等,于是每个人分别去喝水、吃饭了;也就是说这n个人不仅仅关注于其所需要完成的A、B任务等等,还都需要分别完成喝水、吃饭等任务(喝什么水、吃什么饭、去哪喝/吃等等具体细节);

aop:你专门指派一个人去关注所有人都需要的需求或任务是什么,找到了之后(比如喝水、吃饭),对于其共同需求专门封装找相应人去完成相关工作,当那n个人需要喝水、吃饭的时候,直接呼喊调用专门送水、送饭的人(对象/类)就可以了,那么这n个人就不用于其自身去关注于水、饭本身了,送来啥(调用啥)就直接使用就可以了;

由这个例子可以看出其两者是相辅相成的,都是为了更加高效、快速的完成最终的任务目标,只是其关注的方向不同而已;oop关注于每一个人(/对象/类)从头到脚、从始到尾每一个步骤和操作,并对其整体进行封装整合;而aop关注于所有人(类/对象)都需要的共同需求和操作等等进行统一整理封装等等;

oop+aop:这样那n个人就可以更好的关注自己的核心业务是什么,比如领导分配的A、B任务等等,可以使其专注于工作,以使更好、更快;核心业务以外的所有人共同事情是aop所关注的。

问题终于技术:让我来看一个具体的代码实现:

**基于Spring的AOP简单实现**开始讲解用Spring AOP的XML实现方式,先定义一个接口:public interface HelloWorld{    void printHelloWorld();    void doPrint();}定义两个接口实现类:public class HelloWorldImpl1 implements HelloWorld{    public void printHelloWorld()    {        System.out.println("Enter HelloWorldImpl1.printHelloWorld()");    }    public void doPrint()    {        System.out.println("Enter HelloWorldImpl1.doPrint()");        return ;    }}public class HelloWorldImpl2 implements HelloWorld{    public void printHelloWorld()    {        System.out.println("Enter HelloWorldImpl2.printHelloWorld()");    }    public void doPrint()    {        System.out.println("Enter HelloWorldImpl2.doPrint()");        return ;    }}横切关注点,这里是打印时间:public class TimeHandler{    public void printTime()    {        System.out.println("CurrentTime = " + System.currentTimeMillis());    }}有这三个类就可以实现一个简单的Spring AOP了,看一下aop.xml的配置:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:aop="http://www.springframework.org/schema/aop"    xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">        <bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />        <bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />        <bean id="timeHandler" class="com.xrq.aop.TimeHandler" />        <aop:config>            <aop:aspect id="time" ref="timeHandler">                <aop:pointcut id="addAllMethod" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />                <aop:before method="printTime" pointcut-ref="addAllMethod" />                <aop:after method="printTime" pointcut-ref="addAllMethod" />            </aop:aspect>        </aop:config></beans>写一个main函数调用一下:public static void main(String[] args){    ApplicationContext ctx =             new ClassPathXmlApplicationContext("aop.xml");    HelloWorld hw1 = (HelloWorld)ctx.getBean("helloWorldImpl1");    HelloWorld hw2 = (HelloWorld)ctx.getBean("helloWorldImpl2");    hw1.printHelloWorld();    System.out.println();    hw1.doPrint();    System.out.println();    hw2.printHelloWorld();    System.out.println();    hw2.doPrint();}运行结果为:CurrentTime = 1446129611993Enter HelloWorldImpl1.printHelloWorld()CurrentTime = 1446129611993CurrentTime = 1446129611994Enter HelloWorldImpl1.doPrint()CurrentTime = 1446129611994CurrentTime = 1446129611994Enter HelloWorldImpl2.printHelloWorld()CurrentTime = 1446129611994CurrentTime = 1446129611994Enter HelloWorldImpl2.doPrint()CurrentTime = 1446129611994看到给HelloWorld接口的两个实现类的所有方法都加上了代理,代理内容就是打印时间基于Spring的AOP使用其他细节1、增加一个横切关注点,打印日志,Java类为:public class LogHandler{    public void LogBefore()    {        System.out.println("Log before method");    }    public void LogAfter()    {        System.out.println("Log after method");    }}<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:aop="http://www.springframework.org/schema/aop"    xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">        <bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />        <bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />        <bean id="timeHandler" class="com.xrq.aop.TimeHandler" />        <bean id="logHandler" class="com.xrq.aop.LogHandler" />        <aop:config>            <aop:aspect id="time" ref="timeHandler" order="1">                <aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />                <aop:before method="printTime" pointcut-ref="addTime" />                <aop:after method="printTime" pointcut-ref="addTime" />            </aop:aspect>            <aop:aspect id="log" ref="logHandler" order="2">                <aop:pointcut id="printLog" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />                <aop:before method="LogBefore" pointcut-ref="printLog" />                <aop:after method="LogAfter" pointcut-ref="printLog" />            </aop:aspect>        </aop:config></beans>测试类不变,打印结果为:CurrentTime = 1446130273734Log before methodEnter HelloWorldImpl1.printHelloWorld()Log after methodCurrentTime = 1446130273735CurrentTime = 1446130273736Log before methodEnter HelloWorldImpl1.doPrint()Log after methodCurrentTime = 1446130273736CurrentTime = 1446130273736Log before methodEnter HelloWorldImpl2.printHelloWorld()Log after methodCurrentTime = 1446130273736CurrentTime = 1446130273737Log before methodEnter HelloWorldImpl2.doPrint()Log after methodCurrentTime = 1446130273737要想让logHandler在timeHandler前使用有两个办法:(1)aspect里面有一个order属性,order属性的数字就是横切关注点的顺序(2)把logHandler定义在timeHandler前面,Spring默认以aspect的定义顺序作为织入顺序2、我只想织入接口中的某些方法修改一下pointcut的expression就好了:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:aop="http://www.springframework.org/schema/aop"    xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">        <bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />        <bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />        <bean id="timeHandler" class="com.xrq.aop.TimeHandler" />        <bean id="logHandler" class="com.xrq.aop.LogHandler" />        <aop:config>            <aop:aspect id="time" ref="timeHandler" order="1">                <aop:pointcut id="addTime" expression="execution(* com.xrq.aop.HelloWorld.print*(..))" />                <aop:before method="printTime" pointcut-ref="addTime" />                <aop:after method="printTime" pointcut-ref="addTime" />            </aop:aspect>            <aop:aspect id="log" ref="logHandler" order="2">                <aop:pointcut id="printLog" expression="execution(* com.xrq.aop.HelloWorld.do*(..))" />                <aop:before method="LogBefore" pointcut-ref="printLog" />                <aop:after method="LogAfter" pointcut-ref="printLog" />            </aop:aspect>        </aop:config></beans>表示timeHandler只会织入HelloWorld接口print开头的方法,logHandler只会织入HelloWorld接口do开头的方法;

后面代码实现来源:http://www.cnblogs.com/hongwz/p/5764917.html

原创粉丝点击