spring AOP详解〇

AOP正在成为软件开发的下一个圣杯。使用AOP,你可以将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。

为了理解AOP如何做到这点,考虑一下记日志的工作。日志本身不太可能是你开发的主程序的主要任务。如果能将“不可见的”、通用的日志代码注入主程序中,那该多好啊。AOP可以帮助你做到。

Spring framework是很有前途的AOP技术。作为一种非侵略性的,轻型的AOP
framework,你无需使用预编译器或其他的元标签,便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP
framework,其他人还是象往常一样编程。

AOP是很多直觉难以理解的术语的根源。幸运的是,你只要理解三个概念,就可以编写AOP模块。这三个概念是:advice,pointcut和advisor。advice是你想向别的程序内部不同的地方注入的代码。pointcut定义了需要注入advice的位置,通常是某个特定的类的一个public方法。advisor是pointcut和advice的装配器,是将advice注入主程序中预定义位置的代码。


既然我们知道了需要使用advisor向主要代码中注入“不可见的”advice,让我们实现一个Spring
AOP的例子。在这个例子中,我们将实现一个before advice,这意味着advice的代码在被调用的public方法开始前被执行。以下是这个before
advice的实现代码:







代码:
package com.company.springaop.test;

import
java.lang.reflect.Method;
import
org.springframework.aop.MethodBeforeAdvice;

public class
TestBeforeAdvice implements MethodBeforeAdvice {

  public
void before(Method m, Object[] args, Object target)
  throws
Throwable {
    System.out.println("Hello world! (by "

        + this.getClass().getName()
 
      + ")");
  }
}
 

接口MethodBeforeAdvice只有一个方法before需要实现,它定义了advice的实现。before方法共用三个参数,它们提供了相当丰富的信息。参数Method
m是advice开始后执行的方法。方法名称可以用作判断是否执行代码的条件。Object[]
args是传给被调用的public方法的参数数组。当需要记日志时,参数args和被执行方法的名称,都是非常有用的信息。你也可以改变传给m的参数,但要小心使用这个功能;编写最初主程序的程序员并不知道主程序可能会和传入参数的发生冲突。Object
target是执行方法m对象的引用。

在下面的BeanImpl类中,每个public方法调用前,都会执行advice:






代码:
package com.company.springaop.test;

public class
BeanImpl implements Bean {

  public void theMethod() {

    System.out.println(this.getClass().getName()
 
      + "." + new
Exception().getStackTrace()[0].getMethodName()
     
  + "()"
        + " says HELLO!");

  }
}

类BeanImpl实现了下面的接口Bean:







代码:
package com.company.springaop.test;

public
interface Bean {
  public void theMethod();
}

虽然不是必须使用接口,但面向接口而不是面向实现编程是良好的编程实践,Spring也鼓励这样做。


pointcut和advice通过配置文件来实现,因此,接下来你只需编写主方法的Java代码:







代码:


package com.company.springaop.test;


import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.FileSystemXmlApplicationContext;


public class Main {

  public static void
main(String[] args) {
    //Read the configuration file

    ApplicationContext ctx
        =
new FileSystemXmlApplicationContext("springconfig.xml");

 
  //Instantiate an object
    Bean x = (Bean)
ctx.getBean("bean");

    //Execute the public method of
the bean (the test)
    x.theMethod();
  }
}

我们从读入和处理配置文件开始,接下来马上要创建它。这个配置文件将作为粘合程序不同部分的“胶水”。读入和处理配置文件后,我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。


仅仅用配置文件便可把程序的每一部分组装起来。






代码:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC  "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">


<beans>
  <!--CONFIG-->
  <bean
id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces">
 
    <value>com.company.springaop.test.Bean</value>

    </property>
    <property
name="target">
      <ref local="beanTarget"/>

    </property>
    <property
name="interceptorNames">
      <list>

        <value>theAdvisor</value>

      </list>
    </property>

  </bean>

  <!--CLASS-->
 
<bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/>


  <!--ADVISOR-->
  <!--Note: An advisor
assembles pointcut and advice-->
  <bean id="theAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

    <property name="advice">
     
<ref local="theBeforeAdvice"/>
    </property>

    <property name="pattern">
     
<value>com/.company/.springaop/.test/.Bean/.theMethod</value>

    </property>
  </bean>


  <!--ADVICE-->
  <bean
id="theBeforeAdvice"
class="com.company.springaop.test.TestBeforeAdvice"/>

</beans>
 

四个bean定义的次序并不重要。我们现在有了一个advice,一个包含了正则表达式pointcut的advisor,一个主程序类和一个配置好的接口,通过工厂ctx,这个接口返回自己本身实现的一个引用。


BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创建一个bean元素,并指定了一个实现类。这就是全部的工作。


advisor通过Spring
framework提供的一个RegexMethodPointcutAdvisor类来实现。我们用advisor的一个属性来指定它所需的advice-bean。第二个属性则用正则表达式定义了pointcut,确保良好的性能和易读性。


最后配置的是bean,它可以通过一个工厂来创建。bean的定义看起来比实际上要复杂。bean是ProxyFactoryBean的一个实现,它是Spring
framework的一部分。这个bean的行为通过一下的三个属性来定义:

  • 属性proxyInterface定义了接口类。

  • 属性target指向本地配置的一个bean,这个bean返回一个接口的实现。

  • 属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意,advisor列表的次序是非常重要的。

Spring工具


虽然你可以手工修改Ant构建脚本,但使用SpringUI(译注:SpringUI现在是Spring
framework的一部分,并改名为spring-ide),使用Spring
AOP变得很简单,只要点点鼠标即可。你可以把SpringUI安装成Eclipse的一个plug-in。然后,你只需在你的project上右击鼠标,并选择“add
Spring Project Nature”。在project属性中,你可以在“Spring
Project”下添加Spring配置文件。在编译前把下面的类库加入project:aopalliance.jar,commons-logging.jar,jakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息:


... (logging information)
Hello world! (by
com.company.springaop.test.TestBeforeAdvice)

com.company.springaop.test.BeanImpl.theMethod() says HELLO!


优点和缺点


Spring比起其他的framework更有优势,因为除了AOP以外,它提供了更多别的功能。作为一个轻型framework,它在J2EE不同的部分都可以发挥作用。因此,即使不想使用Spring
AOP,你可能还是想使用Spring。另一个优点是,Spring并不要求开发团队所有的人员都会用它。学习Spring应该从Spring
reference的第一页开始。读了本文后,你应该可以更好地理解Spring reference了。Spring唯一的缺点是缺乏更多的文档,但它的mailing
list是个很好的补充,而且会不断地出现更多的文档。

spring AOP详解〇,布布扣,bubuko.com

时间: 2024-10-13 03:02:32

spring AOP详解〇的相关文章

Spring AOP详解(转载)

此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,仔细思考之后,觉得采用AOP 来解决.一方面是为了以更加灵活的方式来解决问题,另一方面是借此机会深入学习Spring AOP相关的内容.本文是权当本人的自己AOP学习笔记,以下需求不用AOP肯定也能解决,至于是否牵强附会,仁者见仁智者见智. 对部分函数的调用进行日志记录,用于观察特定问题在运行过程中的函数调用情况 监控部分重要函数,若抛出指定的异常,需要以短信或邮件方式通知相关人员

Spring AOP详解(转载)所需要的包

上一篇文章中,<Spring Aop详解(转载)>里的代码都可以运行,只是包比较多,中间缺少了几个相应的包,根据报错,几经百度搜索,终于补全了所有包. 截图如下: 在主测试类里面,有人怀疑,没有main方法,是怎么运行的.这是用的junit,结合spring来进行的测试类. Spring AOP详解(转载)所需要的包,布布扣,bubuko.com

Spring AOP 详解 【转】

此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,仔细思考之后,觉得采用AOP 来解决.一方面是为了以更加灵活的方式来解决问题,另一方面是借此机会深入学习Spring AOP相关的内容.本文是权当本人的自己AOP学习笔记,以下需求不用AOP肯定也能解决,至于是否牵强附会,仁者见仁智者见智. 对部分函数的调用进行日志记录,用于观察特定问题在运行过程中的函数调用情况 监控部分重要函数,若抛出指定的异常,需要以短信或邮件方式通知相关人员

Spring—AOP详解

推荐文章:    Spring—AOP详解:https://blog.csdn.net/q982151756/article/details/80513340 轻松理解AOP思想(面向切面编程):https://www.cnblogs.com/Wolfmanlq/p/6036019.html AOP那点事儿:面向切面编程:https://my.oschina.net/huangyong/blog/161338 OOP的完美点缀—AOP之SpringAOP实现原理:https://www.cnbl

细说Spring——AOP详解(动态代理实现AOP)

前言 嗯,我应该是有一段实现没有写过博客了,在写完了细说Spring——AOP详解(AOP概览)之后,我发现我不知道该怎么写AOP这一部分,所以就把写博客这件事给放下了,但是这件事情又不想就这么放弃,所以今天我仔细思考了一下,决定还是要克服困难,我仔细的想了一下怎么讲解AOP实现这一部分,然后我决定由浅入深的讲解动态代理,然后用动态代理实现一个简单的AOP,感觉这样能够让人对AOP的原理有一个比较深刻的认识,希望能帮到大家.而且最近学习又组建了ACM比赛的队伍,虽然已经要大三了,按理来说应该一心

Spring系列(四):Spring AOP详解

一.AOP是什么 AOP(面向切面编程),可以说是一种编程思想,其中的Spring AOP和AspectJ都是现实了这种编程思想.相对OOP(面向过程编程)来说,提供了另外一种编程方式,对于OOP过程中产生的横切性问题,这些横切性与业务无关,可以通过预编译方式和运行期动态代理来实现.比如可以应用在:日志记录.性能监控.事务管理等. 二.AOP的基本概念 Aspect(切面):通常来说是一个类,里面定义了切点和通知,Spring AOP中可以用@AspectJ来标注这个类是切面: Join poi

Spring AOP 详解

详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt117 此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,仔细思考之后,觉得采用AOP 来解决.一方面是为了以更加灵活的方式来解决问题,另一方面是借此机会深入学习Spring AOP相关的内容.本文是权当本人的自己AOP学习笔记,以下需求不用AOP肯定也能解决,至于是否牵强附会,仁者见仁智者见智. 对部分函数的

Spring AOP详解 、 JDK动态代理、CGLib动态代理

AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码通过横向切割的方式抽取到一个独立的模块中. 一.AOP术语 1.连接点(Joinpoint) 程序执行的某个特定位置:如类开始初始化之前.类初始化之后.类某个方法调用前.调用后等:一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就成为“连接点”,Spring仅支持方法的连接点,即

spring aop详解

AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.OOP引入封装.继承.多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合.不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能.日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性.异常处理和透明的持续性也都是如此,这种散布在各