为讲解例子,我们首先定义一个Performance接口:

 package aoptest;

 public interface Performance {
public void perform();
}

再定义一个该接口的实现:

 package aoptest;

 public class PianoPerform implements Performance {

     @Override
public void perform() {
// TODO Auto-generated method stub
System.out.println("i am playing piano");
} }

在创建切面之前,我们先来看一下切点表达式的用法,如图所示:

关于切点表达式的更多用法,可查看相关文档。

接着,我们使用注解定义一个切面,Audience类会在perform方法执行前后织入指定的方法

 package aoptest;

 import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*; @Aspect
public class Audience { @Pointcut("execution(** aoptest.Performance.perform(..))")
public void performance() {}
//performance()方法的实际内容并不重要,在这里它是空的。
//其实该方法本身只是一个标识,供@Pointcut注解依附
//不这样做的话,就需要在每个方法前都使用这个长点的表达式 @Before("performance()")
public void silenceCellPhones() {
System.out.println("Slience cell phones");
} @Before("performance()")
public void takeSeats() {
System.out.println("takeSeats");
} @AfterReturning("performance()")
public void applause() {
System.out.println("applause");
} @AfterThrowing("performance()")
public void demandRefund() {
System.out.println("demandRefund");
}
}
  • @Before:通知方法会在目标方法调用之前调用
  • @AfterReturning:通知方法在目标方法成功返回后调用
  • @AfterThrowing:通知方法在目标方法抛出异常后调用
  • @Around:通知方法会将目标方法封装起来



接着,进行测试,首先使用JavaConfig进行相关bean的配置:

 package aoptest;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@EnableAspectJAutoProxy //启用aspectJ自动代理
@ComponentScan
public class AopConfig {
@Bean
public Audience audience() {
return new Audience();
} @Bean
Performance performance() {
return new PianoPerform();
}
}

然后,创建测试类:

 package aoptest;

 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; //用于在测试开始时自动创建Spring上下文
@RunWith(SpringJUnit4ClassRunner.class)
//告诉上下文需要在AopConfig中加载配置
@ContextConfiguration(classes = { AopConfig.class })
public class PerformTest {
@Autowired
public Audience audience;
@Autowired
public Performance performance;
@Test
public void play() {
performance.perform();
}
}

测试结果,符合预期:

现在,我们利用@Around创建环绕通知,重新实现切面,可以达到相同的效果:

package aoptest;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*; @Aspect
public class Audience { @Pointcut("execution(** aoptest.Performance.perform(..))")
public void performance() {}
//performance()方法的实际内容并不重要,在这里它是空的。
//其实该方法本身只是一个标识,供@Pointcut注解依附
//不这样做的话,就需要在每个方法前都使用这个长点的表达式 @Around("performance()")
//ProceedingJoinPoint这个对象是必须有的,因为需要通过它来调用被通知的方法,使用proceed()方法
public void watchPerformance(ProceedingJoinPoint jp) {
System.out.println("Slience cell phones");
System.out.println("takeSeats");
try {
jp.proceed();
} catch (Throwable e) {
System.out.println("demandRefund");
}
System.out.println("applause");
}
}

当然,你也可以不调用proceed()方法,从而阻塞对通知方法的访问。

Sping——使用注解创建切面的更多相关文章

  1. Spring AOP之使用注解创建切面

    上节中我们已经定义了Performance接口,他是切面中的切点的一个目标对象.那么现在就让我们使用AspectJ注解来定义切面吧. 1.定义切面 下面我们就来定义一场舞台剧中观众的切面类Audien ...

  2. SpringInAction--面向切片的Spring以及如何使用注解创建切面

    什么叫做切片..什么叫做AOP... 与大多数技术一样,AOP已经形成了自己的术语.描述切面的常用术语有通知(advice).切点(pointcut)和连接点(join point). (一大串书上的 ...

  3. Spring AOP中使用@Aspect注解 面向切面实现日志横切功能详解

    引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一 ...

  4. 基于@AspectJ注解配置切面与基于XML配置切面

    1. Waiter目标类 package com.smart.aop.advice.pointcut; public class Waiter { public void greetTo(String ...

  5. 010-Spring aop 001-核心说明-拦截指定类与方法、基于自定义注解的切面

    一.概述 面向切面编程(AOP)是针对面向对象编程(OOP)的补充,可以非侵入式的为多个不具有继承关系的对象引入相同的公共行为例如日志.安全.事务.性能监控等等.SpringAOP允许将公共行为从业务 ...

  6. 使用@Async注解创建多线程,自定义线程池

    说明 使用@Async注解创建多线程非常的方便,还可以通过配置,实现线程池.比直接使用线程池简单太多.而且在使用上跟普通方法没什么区别,加上个@Async注解即可实现异步调用. 用法 AsyncTas ...

  7. Spring Boot 使用 @Scheduled 注解创建定时任务

    在项目开发中我们经常需要一些定时任务来处理一些特殊的任务,比如定时检查订单的状态.定时同步数据等等. 在 Spring Boot 中使用 @Scheduled 注解创建定时任务非常简单,只需要两步操作 ...

  8. 【快学springboot】10.使用@Async注解创建多线程,自定义线程池

    说明 使用@Async注解创建多线程非常的方便,还可以通过配置,实现线程池.比直接使用线程池简单太多.而且在使用上跟普通方法没什么区别,加上个@Async注解即可实现异步调用. 用法 AsyncTas ...

  9. 自定义注解结合切面和spel表达式

    在我们的实际开发中可能存在这么一种情况,当方法参数中的某些条件成立的时候,需要执行一些逻辑处理,比如输出日志.而这些代码可能都是差不多的,那么这个时候就可以结合自定义注解加上切面加上spel表达式进行 ...

随机推荐

  1. 友盟 个推 微信sdk spring boot

    友盟 个推 微信sdk spring boot ngix mongodb memory cache

  2. ftk学习记(输入框篇)

    [ 声明:版权全部.欢迎转载.请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 昨天讲了进度条,我们还是看看它的运行效果是怎么样的.截图例如以下, 进度条使用的情况还是比較多的 ...

  3. C++学习之可变参数的函数与模板

    所谓可变参数指的是函数的参数个数可变,参数类型不定的函数.为了编写能处理不同数量实参的函数,C++11提供了两种主要的方法:如果所有的实参类型相同,可以传递一个名为initializer_list的标 ...

  4. JavaScript的原生引用类型

    引用类型是一种数据结构,用于将数据和功能组织在一起,也常称做类.ECMAScript从技术上说是一门面向对象的语言.但它不具备传统的面向对象语言所支持的类和接口等基本结构. Object类型 大多数引 ...

  5. 利用 gnuplot_i 在你的 c 程序中调用 GNUPLOT

    这是一篇非常早曾经写的小文章,最初发表于我的搜狐博客(2008-09-23 22:55).由于自从转移到这里后,sohu 博客就不再维护了,所以把这篇文章也一起挪了过来. GNUPLOT 是一款功能强 ...

  6. 跨平台C、C++代码注意的事项

    在我们的开发中,跨平台的需求越来越强烈,怎样保持C/C++代码能在多个平台上编译,是一个比較值得研究的问题.关于跨平台的文章网上非常多,跨平台的库网上也非常多.那么我从自己的跨平台开发经验谈一谈自己的 ...

  7. 技术的止境(客户价值第一,快速实现第二,边做边学,迅速成为牛人。紧贴客户的需求去做技术,立于不败之地。追求的目标:把一项产品去做好,用产品去养活自己和家人)good

    作为一个依靠技术来谋生的程序员,我最近一直在思考一个问题,有限的生命里,面对无限的技术更新,我要研究到什么程度才能算是完成我的成为技术大牛的目标呢?换而言之,那就是技术的止境在哪儿呢?深入的思考下去, ...

  8. luogu2346 四子连棋

    题目大意 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以 ...

  9. JPush 初始化失败,直接按照官方文档的格式写的,portal上的包名肯定不会错,mainfest里面直接指定${applicationId}

    错误日志: 11-27 09:59:19.670 26124-26124/? D/dalvikvm: Late-enabling CheckJNI 11-27 09:59:20.008 26124-2 ...

  10. JSP-Runoob:JSP JavaBean

    ylbtech-JSP-Runoob:JSP JavaBean 1.返回顶部 1. JSP JavaBean JavaBean是特殊的Java类,使用J ava语言书写,并且遵守JavaBean AP ...