Spring 中基于 AOP 的 @AspectJ

@AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格。

通过在你的基于架构的 XML 配置文件中包含以下元素,@AspectJ 支持是可用的。

<aop:aspectj-autoproxy/>

声明一个 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(){
...
}

基于 AOP 的 @AspectJ 示例

  • 新建Spring项目

  • 在项目中添加 Spring AOP 指定的库文件 aspectjrt.jar, aspectjweaver.jar 和 aspectj.jar。

  • 保证aspectjweaver.jar的版本在1.8以上,否则会报错。

  • 创建 Java 类 Logging, Student 和 MainApp

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

package hello;
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; //import org.springframework.aop.aspectj.AspectJAfterThrowingAdvice;
@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(* hello.*.*(..))")
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.
*/
@AfterThrowing(pointcut = "selectAll()", throwing = "ex")
public void AfterThrowingAdvice(IllegalArgumentException ex){
System.out.println("there has been an exception:"+ex.toString());
}
}

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

package hello;
//import org.springframework.beans.factory.annotation.Autowired; public class Student {
private int age;
private String name;
public void setAge(int age){
this.age = age;
}
public int 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 hello;
//import org.springframework.context.support.AbstractApplicationContext;
//import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
//import org.springframework.context.annotation.*; 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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--aop:config>
<aop:aspect id="log" ref="logging">
<aop:pointcut id="selectAll" expression="execution(* hello.*.*(..))"/>
<aop:before pointcut-ref="selectAll" method="beforeAdvice"/>
<aop:after pointcut-ref="selectAll" method="afterAdvice"/>
<aop:after-returning pointcut-ref="selectAll"
returning="retVal"
method="afterReturningAdvice"/>
<aop:after-throwing pointcut-ref="selectAll"
throwing="ex"
method="AfterThrowingAdvice"/>
</aop:aspect>
</aop:config--> <aop:aspectj-autoproxy/> <!-- Definition for student bean -->
<bean id="student" class="hello.Student">
<property name="name" value="番茄"/>
<property name="age" value="10"/>
</bean> <!-- Definition for logging aspect -->
<bean id="logging" class="hello.Logging">
</bean> </beans>

运行一下应用程序

Going to setup student profile.
name:番茄
Student profile has been setup
Returning:番茄
Going to setup student profile.
age:10
Student profile has been setup
Returning:10 Process finished with exit code 0

每天学习一点点,每天进步一点点。

Spring 中基于 AOP 的 @AspectJ的更多相关文章

  1. Spring中基于AOP的@AspectJ

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/aop-with-spring-framenwork/aspectj-based-aop-with- ...

  2. Spring 中基于 AOP 的 @AspectJ注解实例

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

  3. Spring 中基于 AOP 的 XML架构

    Spring 中基于 AOP 的 XML架构 为了使用 aop 命名空间标签,你需要导入 spring-aop j架构,如下所述: <?xml version="1.0" e ...

  4. Spring中基于AOP的XML架构

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/aop-with-spring-framenwork/xml-schema-based-aop-wi ...

  5. spring中基于aop使用ehcache

    我就是对着这个博客看的 http://www.cnblogs.com/ctxsdhy/p/6421016.html

  6. Spring中基于xml的AOP

    1.Aop 全程是Aspect Oriented Programming 即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术.Aop是oop的延续,是软件开发中的 一个热点 ...

  7. spring中基于注解使用AOP

    本文内容:spring中如何使用注解实现面向切面编程,以及如何使用自定义注解. 一个场景 比如用户登录,每个请求发起之前都会判断用户是否登录,如果每个请求都去判断一次,那就重复地做了很多事情,只要是有 ...

  8. Spring中的AOP 专题

    Caused by: java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advi ...

  9. JavaWeb_(Spring框架)认识Spring中的aop

    1.aop思想介绍(面向切面编程):将纵向重复代码,横向抽取解决,简称:横切 2.Spring中的aop:无需我们自己写动态代理的代码,spring可以将容器中管理对象生成动态代理对象,前提是我们对他 ...

随机推荐

  1. Struts2漏洞利用

    Struts漏洞合集 Struts-S2-013漏洞利用 受影响版本 Struts 2.0.0 - Struts 2.3.14.1 漏洞利用 任意命令执行POC: ${(#_memberAccess[ ...

  2. React-Native iOS真机调试(新版)

    2019独角兽企业重金招聘Python工程师标准>>> React-Native iOS真机调试 看到网上很多以前的文章 找到两种方法 一 修改AppDelegate 把URL的替换 ...

  3. Longest XXX

    Longest Common Substring Brute Force 遍历a和b所有位置的组合,向后延伸,直到遇到两个不同的字符,复杂度是\(n^3\)级别. class Solution { p ...

  4. 2019年 ICPC亚洲区预赛(上海赛区)总结

    首先,我要说,我输了,输给了自己的无知,输给了自己的心态与实力. 上海区域赛,打铁而归,最终还是没有比过自己SLG的朋友.要说什么呢?实力的差距,还是说给自己的失败找借口?不能进入金牌区,为什么铜牌区 ...

  5. 洛谷 P1816 忠诚 ST函数

    题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了 ...

  6. 题解 AT4867 【[ABC155D] Pairs】

    题目 两次二分 首先对ans进行二分,在\([-10^{18},10^{18}]\)之间 考虑怎么check 对于每个ans,枚举每个\(a_i\),二分查找有几个\(a_j\),使得\(a_i\ti ...

  7. BSGS 和扩展

    BSGS BSGS,全称叫 BabyStepGiantStep,也就是大步小步 其实还是比较暴力的 它可以\(O(\sqrt p)\)的复杂度内解出: \[a^x\equiv n\pmod p,\gc ...

  8. RF(用例执行方法)

    一.执行 RF 脚本方法 1.执行整个项目下的所有用例 dos 窗口下输入 robot + 项目绝对路径 2.执行单个 Suite 中的所有用例 dos 窗口下输入 robot + 用例套件绝对路径 ...

  9. php扩展开发之hello world

    最近在公司做的事情就是php扩展开发,虽然我只负责c++代码的编写,但是了解扩展开发的流程还是很有必要的. (本文介绍的是动态扩展,对静态扩展有兴趣的读者可自行google) php扩展开发环境搭建可 ...

  10. Java——多线程之方法详解

    Java多线程系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多 ...