Spring使用AspectJ开发AOP:基于Annotation
基于 Annotation 的声明式
在 Spring 中,尽管使用 XML 配置文件可以实现 AOP 开发,但是如果所有的相关的配置都集中在配置文件中,势必会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。
为此,AspectJ 框架为 AOP 开发提供了另一种开发方式——基于 Annotation 的声明式。AspectJ 允许使用注解定义切面、切入点和增强处理,而 Spring 框架则可以识别并根据这些注解生成 AOP 代理。
关于 Annotation 注解的介绍如表 1 所示。
| 名称 | 说明 |
|---|---|
| @Aspect | 用于定义一个切面。 |
| @Before | 用于定义前置通知,相当于 BeforeAdvice。 |
| @AfterReturning | 用于定义后置通知,相当于 AfterReturningAdvice。 |
| @Around | 用于定义环绕通知,相当于MethodInterceptor。 |
| @AfterThrowing | 用于定义抛出通知,相当于ThrowAdvice。 |
| @After | 用于定义最终final通知,不管是否异常,该通知都会执行。 |
| @DeclareParents | 用于定义引介通知,相当于IntroductionInterceptor(不要求掌握)。 |
下面使用注解的方式重新实现《基于XML的声明式》部分的功能。
1. 创建切面类 MyAspect
在 src 目录下创建一个名为 com.mengma.aspectj.annotation 的包,在该包下创建一个切面类 MyAspect,如下所示。
package com.mengma.aspectj.annotation; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; //切面类
@Aspect
@Component
public class MyAspect {
// 用于取代:<aop:pointcut
// expression="execution(*com.mengma.dao..*.*(..))" id="myPointCut"/>
// 要求:方法必须是private,没有值,名称自定义,没有参数
@Pointcut("execution(*com.mengma.dao..*.*(..))")
private void myPointCut() {
} // 前置通知
@Before("myPointCut()")
public void myBefore(JoinPoint joinPoint) {
System.out.print("前置通知,目标:");
System.out.print(joinPoint.getTarget() + "方法名称:");
System.out.println(joinPoint.getSignature().getName());
} // 后置通知
@AfterReturning(value = "myPointCut()")
public void myAfterReturning(JoinPoint joinPoint) {
System.out.print("后置通知,方法名称:" + joinPoint.getSignature().getName());
} // 环绕通知
@Around("myPointCut()")
public Object myAround(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
System.out.println("环绕开始"); // 开始
Object obj = proceedingJoinPoint.proceed(); // 执行当前目标方法
System.out.println("环绕结束"); // 结束
return obj;
} // 异常通知
@AfterThrowing(value = "myPointCut()", throwing = "e")
public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
System.out.println("异常通知" + "出错了" + e.getMessage());
} // 最终通知
@After("myPointCut()")
public void myAfter() {
System.out.println("最终通知");
}
}
上述代码中,第 13 行 @Aspect 注解用于声明这是一个切面类,该类作为组件使用,所以要添加 @Component 注解才能生效。第 19 行中 @Poincut 注解用于配置切入点,取代 XML 文件中配置切入点的代码。
在每个通知相应的方法上都添加了注解声明,并且将切入点方法名“myPointCut”作为参数传递给要执行的方法,如需其他参数(如异常通知的异常参数),可以根据代码提示传递相应的属性值。
2. 为目标类添加注解
在 com.mengma.dao.CustomerDaoImpl 目标类中添加注解 @Repository("customerDao")。
import org.springframework.stereotype.Repository;
@Repository("customerDao")
public class CustomerDao {
public void doSome(){
// int i=1/0;
System.out.println("正式业务");
}
}
3. 创建Spring配置文件
在 com.mengma.aspectj.annotation 包下创建 applicationContext.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-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描含com.mengma包下的所有注解-->
<context:component-scan base-package="com.mengma"/>
<!-- 使切面开启自动代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
上述代码中,首先导入了 AOP 命名空间及其配套的约束,使切面类中的 @AspectJ 注解能够正常工作;第 13 行代码添加了扫描包,使注解生效。需要注意的是,这里还包括目标类 com.mengma.dao.CustomerDaoImpl 的注解,所以 base-package 的值为 com.mengma;第 15 行代码的作用是切面开启自动代理。
4. 创建测试类
在 com.mengma.aspectj.annotation 包下创建一个名为 AnnotationTest 的测试类,如下所示。
package com.mengma.aspectj.annotation; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mengma.dao.CustomerDao; public class AnnotationTest {
@Test
public void test() {
String xmlPath = "com/mengma/aspectj/xml/applicationContext.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
xmlPath);
// 从spring容器获取实例
CustomerDao customerDao = (CustomerDao) applicationContext
.getBean("customerDao");
// 执行方法
customerDao.add();
}
}
5. 运行项目并查看结果
使用 JUnit 测试运行 test() 方法,运行成功后,控制台的输出结果如图 3 所示。

图 3 运行结果
删除 add() 方法中的“int i=1/0;”,重新运行 test() 方法,此时控制台的输出结果如图 4 所示。

图 4 运行结果
从图 3 和图 4 的输出结果中可以看出,已成功使用 Annotation 的方式实现了 AOP 开发。与其他方式相比,基于 Annotation 方式实现 AOP 的效果是最方便的方式,所以实际开发中推荐使用注解的方式。
Spring使用AspectJ开发AOP:基于Annotation的更多相关文章
- 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring使用AspectJ开发AOP基于XML和基于Annotation
AspectJ 是一个基于 Java 语言的 AOP 框架,它扩展了 Java 语言.Spring 2.0 以后,新增了对 AspectJ 方式的支持,新版本的 Spring 框架,建议使用 Aspe ...
- Spring使用AspectJ开发AOP:基于XML
基于XML的声明式 基于 XML 的声明式是指通过 Spring 配置文件的方式定义切面.切入点及声明通知,而所有的切面和通知都必须定义在 <aop:config> 元素中. 下面通过案例 ...
- Spring使用@AspectJ开发AOP(零配置文件)
前言: AOP并不是Spring框架特有的.Spring只是支持AOP编程 (面向切面编程) 的框架之一. 概念: 1.切面(Aspect) 一系列Advice + Pointcut 的集合. 2.通 ...
- (转)Spring使用AspectJ进行AOP的开发:注解方式
http://blog.csdn.net/yerenyuan_pku/article/details/69790950 Spring使用AspectJ进行AOP的开发:注解方式 之前我已讲过Sprin ...
- Spring整合AspectJ的AOP
学而时习之,不亦说乎! --<论语> 看这一篇之前最好先看前面关于AOP的两篇. http://www.cnblogs.com/z ...
- 在Spring整合aspectj实现aop的两种方式
-----------------------------基于XML配置方案目标对象接口1 public interface IUserService { public void add(); pub ...
- spring与hibernate整合配置基于Annotation注解方式管理实务
1.配置数据源 数据库连接基本信息存放到properties文件中,因此先加载properties文件 <!-- jdbc连接信息 --> <context:property-pla ...
- 不依赖Spring使用AspectJ达到AOP面向切面编程
网上大多数介绍AspectJ的文章都是和Spring容器混用的,但有时我们想自己写框架就需要抛开Spring造轮子,类似使用原生AspectJ达到面向切面编程.步骤很简单,只需要两步. 1.导入依赖 ...
- Spring -- aop, 用Aspectj进行AOP开发
1. 概要 添加类库:aspectjrt.jar和aspectjweaver.jar 添加aop schema. 定义xml元素:<aop:aspectj-autoproxy> 编写jav ...
随机推荐
- 解决commBind: Cannot bind socket FD 18 to [::1]: (99) Cannot assign requested address squid
最近玩squid主要是为了爬虫代理,但是使用docker搭建squid的时候发现,docker一直默认使用的 ipv6,但是squid使用ipv4,导致无法绑定,出现commBind: Cannot ...
- css3不定宽高水平垂直居中
1 justify-content:center;//子元素水平居中 2 align-items:center;//子元素垂直居中 3 display:-webkit-flex; 在父级元素上面加上上 ...
- FPGA、GPU、CPU三者各自的优缺点是什么呢?
CPU: 英文全称:Central Processing Unit. 中文全称:中央处理器. 厂商:英特尔Intel. 功能:是一台计算机的运算核心和控制核心. 缺点:运算能力(最弱),核处理数(最少 ...
- Wordpress对接小程序配置过程
最近发现一个很棒的开源项目-WordPress版微信小程序 https://github.com/iamxjb/winxin-app-watch-life.net,详细看了下介绍非常棒,不仅支持的功 ...
- jenkins上下游工程以及空间占用处理
1.最近项目架构调整,把十几个java项目整合为一个大的项目,这样构建上游工程成功后下游工程会自动构建 解决如下:取消这个勾选即可 2.构建单个项目时,会把所有子工程都打包一次 解决如下:指定构建时的 ...
- selenium-01-2环境搭建
首先下载好Eclipse 和配置好Java 环境变量 步骤省略, 请百度 方法一 添加jar包 官方下载地址: http://www.seleniumhq.org/download/ 官方地址 ...
- 数据分析--Matplotlib的基本使用
一.Matplotlib概述 1.Matplotlib是一个强大的Python绘图和数据可视化的工具包. 2.python中操作方式: 安装方法:pip install matplotlib 引用方法 ...
- Spring Boot 梳理 - 4个核心
Spring Boot 魔法的核心:自动配置.起步依赖.命令行界面.Actuator 自动配置: 不用手动配置JdbcTemplate的Bean 不用手动配置DataSource的Bean Sprin ...
- ReactNative实现GridView
ReactNative内置了ListView组件但是没有类似GridView这样的组件.利用一些已经有的属性是可以实现GridView的,利用ContentContainerStyle的属性然后配合样 ...
- IT架构师技术知识图谱
互联网上“最全的技术图谱”,记录下.来源:http://developer.51cto.com/art/201708/548757.htm 1 1.1 架构师图谱 1.2 Java架构师图谱 1.3 ...