Spring基础 专题
专题目录
您的位置:java > Spring基础专题 > Spring 中基于 AOP 的 @AspectJ
Spring 中基于 AOP 的 @AspectJ
作者:--    发布时间:2019-11-20

@aspectj 作为通过 java 5 注释注释的普通的 java 类,它指的是声明 aspects 的一种风格。通过在你的基于架构的 xml 配置文件中包含以下元素,@aspectj 支持是可用的。

<aop:aspectj-autoproxy/>

你还需要在你的应用程序的 classpath 中使用以下 aspectj 库文件。这些库文件在一个 aspectj 装置的 ‘lib’ 目录中是可用的,如果没有,你可以在 internet 中下载它们。

  • aspectjrt.jar

  • aspectjweaver.jar

  • aspectj.jar

  • aopalliance.jar

 声明一个 aspect

aspects 类和其他任何正常的 bean 一样,除了它们将会用 @aspectj 注释之外,它和其他类一样可能有方法和字段,如下所示:

package org.xyz;
import org.aspectj.lang.annotation.aspect;
@aspect
public class aspectmodule {
}

它们将在 xml 中按照如下进行配置,就和其他任何 bean 一样:

<bean id="myaspect" class="org.xyz.aspectmodule">
   <!-- configure properties of aspect here as normal -->
</bean>

声明一个切入点

一个切入点有助于确定使用不同建议执行的感兴趣的连接点(即方法)。在处理基于配置的 xml 架构时,切入点的声明有两个部分:

  • 一个切入点表达式决定了我们感兴趣的哪个方法会真正被执行。

  • 一个切入点标签包含一个名称和任意数量的参数。方法的真正内容是不相干的,并且实际上它应该是空的。

下面的示例中定义了一个名为 ‘businessservice’ 的切入点,该切入点将与 com.xyz.myapp.service 包下的类中可用的每一个方法相匹配:

import org.aspectj.lang.annotation.pointcut;
@pointcut("execution(* com.xyz.myapp.service.*.*(..))") // expression 
private void businessservice() {}  // signature

下面的示例中定义了一个名为 ‘getname’ 的切入点,该切入点将与 com.tutorialspoint 包下的 student 类中的 getname() 方法相匹配:

import org.aspectj.lang.annotation.pointcut;
@pointcut("execution(* com.tutorialspoint.student.getname(..))") 
private void getname() {}

声明建议

你可以使用 @{advice-name} 注释声明五个建议中的任意一个,如下所示。这假设你已经定义了一个切入点标签方法 businessservice():

@before("businessservice()")
public void dobeforetask(){
 ...
}
@after("businessservice()")
public void doaftertask(){
 ...
}
@afterreturning(pointcut = "businessservice()", returning="retval")
public void doafterreturnningtask(object retval){
  // you can intercept retval here.
  ...
}
@afterthrowing(pointcut = "businessservice()", throwing="ex")
public void doafterthrowingtask(exception ex){
  // you can intercept thrown exception here.
  ...
}
@around("businessservice()")
public void doaroundtask(){
 ...
}

你可以为任意一个建议定义你的切入点内联。下面是在建议之前定义内联切入点的一个示例:

@before("execution(* com.xyz.myapp.service.*.*(..))")
public dobeforetask(){
 ...
}

基于 aop 的 @aspectj 示例

为了理解上面提到的关于基于 aop 的 @aspectj 的概念,让我们编写一个示例,可以实现几个建议。为了在我们的示例中使用几个建议,让我们使 eclipse ide 处于工作状态,然后按照如下步骤创建一个 spring 应用程序:

步骤 描述
1 创建一个名为 springexample 的项目,并且在所创建项目的 src 文件夹下创建一个名为 com.tutorialspoint 的包。
2 使用 add external jars 选项添加所需的 spring 库文件,就如在 spring hello world example 章节中解释的那样。
3 在项目中添加 spring aop 指定的库文件 aspectjrt.jar, aspectjweaver.jaraspectj.jar
4 com.tutorialspoint 包下创建 java 类 loggingstudentmainapp
5 src 文件夹下创建 beans 配置文件 beans.xml
6 最后一步是创建所有 java 文件和 bean 配置文件的内容,并且按如下解释的那样运行应用程序。

这里是 logging.java 文件的内容。这实际上是 aspect 模块的一个示例,它定义了在各个点调用的方法。

package com.tutorialspoint;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.pointcut;
import org.aspectj.lang.annotation.before;
import org.aspectj.lang.annotation.after;
import org.aspectj.lang.annotation.afterthrowing;
import org.aspectj.lang.annotation.afterreturning;
import org.aspectj.lang.annotation.around;
@aspect
public class logging {
   /** following is the definition for a pointcut to select
    *  all the methods available. so advice will be called
    *  for all the methods.
    */
   @pointcut("execution(* com.tutorialspoint.*.*(..))")
   private void selectall(){}
   /** 
    * this is the method which i would like to execute
    * before a selected method execution.
    */
   @before("selectall()")
   public void beforeadvice(){
      system.out.println("going to setup student profile.");
   }
   /** 
    * this is the method which i would like to execute
    * after a selected method execution.
    */
   @after("selectall()")
   public void afteradvice(){
      system.out.println("student profile has been setup.");
   }
   /** 
    * this is the method which i would like to execute
    * when any method returns.
    */
   @afterreturning(pointcut = "selectall()", returning="retval")
   public void afterreturningadvice(object retval){
      system.out.println("returning:" + retval.tostring() );
   }
   /**
    * this is the method which i would like to execute
    * if there is an exception raised by any method.
    */
   @afterthrowing(pointcut = "selectall()", throwing = "ex")
   public void afterthrowingadvice(illegalargumentexception ex){
      system.out.println("there has been an exception: " + ex.tostring());   
   }  
}

下面是 student.java 文件的内容:

package com.tutorialspoint;
public class student {
   private integer age;
   private string name;
   public void setage(integer age) {
      this.age = age;
   }
   public integer getage() {
      system.out.println("age : " + age );
      return age;
   }
   public void setname(string name) {
      this.name = name;
   }
   public string getname() {
      system.out.println("name : " + name );
      return name;
   }
   public void printthrowexception(){
      system.out.println("exception raised");
      throw new illegalargumentexception();
   }
}

下面是 mainapp.java 文件的内容:

package com.tutorialspoint;
import org.springframework.context.applicationcontext;
import org.springframework.context.support.classpathxmlapplicationcontext;
public class mainapp {
   public static void main(string[] args) {
      applicationcontext context = 
             new classpathxmlapplicationcontext("beans.xml");
      student student = (student) context.getbean("student");
      student.getname();
      student.getage();     
      student.printthrowexception();
   }
}

下面是配置文件 beans.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"
    xsi:schemalocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

    <aop:aspectj-autoproxy/>

   <!-- definition for student bean -->
   <bean id="student" class="com.tutorialspoint.student">
      <property name="name"  value="zara" />
      <property name="age"  value="11"/>      
   </bean>

   <!-- definition for logging aspect -->
   <bean id="logging" class="com.tutorialspoint.logging"/> 

</beans>

一旦你已经完成的创建了源文件和 bean 配置文件,让我们运行一下应用程序。如果你的应用程序一切都正常的话,这将会输出以下消息:

going to setup student profile.
name : zara
student profile has been setup.
returning:zara
going to setup student profile.
age : 11
student profile has been setup.
returning:11
going to setup student profile.
exception raised
student profile has been setup.
there has been an exception: java.lang.illegalargumentexception
.....
other exception content


网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册