Spring AOP 使用注解定义切面(转载)
原文地址:http://www.jianshu.com/p/6f40dddd71a5
1.定义切面
下面我们就来定义一场舞台剧中观众的切面类Audience:
package com.spring.aop.service.aop;
import org.aspectj.lang.ProceedingJoinPoint;
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;
/**
* <dl>
* <dd>Description:观看演出的切面</dd>
* <dd>Company: 黑科技</dd>
年9月3日下午9:58:09</dd>
* <dd>@author:Kong</dd>
* </dl>
*/
@Aspect
public class Audience {
/**
* 目标方法执行之前调用
*/
@Before("execution(** com.spring.aop.service.perform(..))")
public void silenceCellPhone() {
System.out.println("Silencing cell phones");
}
/**
* 目标方法执行之前调用
*/
@Before("execution(** com.spring.aop.service.perform(..))")
public void takeSeats() {
System.out.println("Taking seats");
}
/**
* 目标方法执行完后调用
*/
@AfterReturning("execution(** com.spring.aop.service.perform(..))")
public void applause() {
System.out.println("CLAP CLAP CLAP");
}
/**
* 目标方法发生异常时调用
*/
@AfterThrowing("execution(** com.spring.aop.service.perform(..))")
public void demandRefund() {
System.out.println("Demanding a refund");
}
}
我们可以看到使用了几种注解,其实AspectJ提供了五中注解来定义通知:
|
注解 |
通知 |
|
@After |
通知方法会在目标方法返回或抛出异常后调用 |
|
@AfterRetruening |
通常方法会在目标方法返回后调用 |
|
@AfterThrowing |
通知方法会在目标方法抛出异常后调用 |
|
@Around |
通知方法将目标方法封装起来 |
|
@Before |
通知方法会在目标方法执行之前执行 |
聪明的你可能已经看到,同样的切点我们写了四遍,这是不科学的,强大的Spring怎么会没有处理的方法呢。其实我们可以使用@Pointcut注解声明一个通用的切点,在后面可以随意使用:
package com.spring.aop.service.aop;
import org.aspectj.lang.ProceedingJoinPoint;
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;
/**
* <dl>
* <dd>Description:观看演出的切面</dd>
* <dd>Company: 黑科技</dd>
年9月3日下午9:58:09</dd>
* <dd>@author:Kong</dd>
* </dl>
*/
@Aspect
public class Audience {
/**
* 定义一个公共的切点
*/
@Pointcut("execution(** com.spring.aop.service.Perfomance.perform(..))")
public void performance() {
}
/**
* 目标方法执行之前调用
*/
@Before("performance()")
public void silenceCellPhone() {
System.out.println("Silencing cell phones");
}
/**
* 目标方法执行之前调用
*/
@Before("performance()")
public void takeSeats() {
System.out.println("Taking seats");
}
/**
* 目标方法执行完后调用
*/
@AfterReturning("performance()")
public void applause() {
System.out.println("CLAP CLAP CLAP");
}
/**
* 目标方法发生异常时调用
*/
@AfterThrowing("performance()")
public void demandRefund() {
System.out.println("Demanding a refund");
}
}
这样定义一个切点后,后面我们的方法想使用这个切点直接调用切点所在的方法就行了。实际上切面也是一个Java类,我们可以将它装配到Spring中的bean中:
/**
* 声明Audience bean
* @return
*/
@Bean
public Audience audience(){
return new Audience();
}
但是现在Spring还不会将Audience视为一个切面,即便使用了@AspectJ注解,但它并不会被视为一个切面们这些注解不会被解析,也不会创建将其转化为切面的代理。但我们可以使用JavaConfig,然后在JavaConfig类上使用注解@EnableAspectJAutoProxy注解启动自动代理功能:
package com.spring.aop.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.spring.aop.service.aop.Audience;
/**
* <dl>
* <dd>Description:配置类</dd>
* <dd>Company: 黑科技</dd>
年9月3日下午10:20:11</dd>
* <dd>@author:Kong</dd>
* </dl>
*/
@Configuration
//启动AspectJ自动代理
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
/**
* 声明Audience bean
* @return
*/
@Bean
public Audience audience(){
return new Audience();
}
}
如果你想使用XML配置也是可以的,我们要使用Spring aop命名空间中的<aop:aspectj-autoproxy>元素:
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">
<context:component-scan base-package="com.spring.aop" />\
<!-- 启动AspectJ自动代理 -->
<aop:aspectj-autoproxy/>
<bean class="com.spring.aop.Audience" />
</beans>
其实不管使用JAvaConfig还是Xml,AspectJ都会为使用@ApsectJ注解的Bean创建一个代理,这个代理会环绕着所有该切面所匹配的bean。
Spring AOP 使用注解定义切面(转载)的更多相关文章
- 利用Spring AOP自定义注解解决日志和签名校验
转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...
- spring aop 使用注解方式总结
spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...
- (转)利用Spring AOP自定义注解解决日志和签名校验
一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...
- spring-第十七篇之spring AOP基于注解的零配置方式
1.基于注解的零配置方式 Aspect允许使用注解定义切面.切入点和增强处理,spring框架可以识别并根据这些注解来生成AOP代理.spring只是用了和AspectJ 5一样的注解,但并没有使用A ...
- spring AOP自定义注解方式实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- spring AOP自定义注解 实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- 基于注解的Spring AOP的配置和使用--转载
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- Spring AOP基于注解的“零配置”方式实现
为了在Spring中启动@AspectJ支持,需要在类加载路径下新增两个AspectJ库:aspectjweaver.jar和aspectjrt.jar.除此之外,Spring AOP还需要依赖一个a ...
- 利用spring AOP 和注解实现方法中查cache-我们到底能走多远系列(46)
主题:这份代码是开发中常见的代码,查询数据库某个主表的数据,为了提高性能,做一次缓存,每次调用时先拿缓存数据,有则直接返回,没有才向数据库查数据,降低数据库压力. public Merchant lo ...
随机推荐
- nodejs之express静态路由、ejs
1.静态路由与ejs使用 /** *1.安装ejs npm install ejs --save-dev * *2.express 里面使用ejs ,安装以后就可以用,不需要引入 * *3.配置exp ...
- 前端必须掌握的 nginx 技能(2)
概述 作为一个前端,我觉得必须要学会使用 nginx 干下面几件事: 代理静态资源 设置反向代理(添加https) 设置缓存 设置 log 部署 smtp 服务 设置 redis 缓存(选) 下面我按 ...
- mysql的性能优化简介
mysql性能下降的原因 sql语句本身有问题,或没建索引 索引失效,索引失效的原因本文后面会叙述 关联了过多的表,可能是前期设计缺陷,或者太奇葩的需求 服务器调优及参数设置,例如缓冲.线程等 mys ...
- Python基本语法_运算符详解
目录 目录 前言 软件环境 身份运算符 算术运算符 比较运算符 位移运算符 自变运算符 位运算符 逻辑运算符 成员关系运算符 Python真值表 最后 前言 在前面的博文介绍了Python的数据结构之 ...
- Android 调用相机、相册功能
清单文件中增加对应权限,动态申请权限(此部分请参考Android 动态申请权限,在此不作为重点描述) private static final int REQUEST_CODE_ALBUM = 100 ...
- abap seach help 搜索帮助
ABAP 的搜索帮助有很多种方法,掌握下面的几种基本差不多了 *&--------------------------------------------------------------- ...
- linux使用df查看硬盘使用率
df 是来自于coreutils 软件包,系统安装时,就自带的:我们通过这个命令可以查看磁盘的使用情况以及文件系统被挂载的位置: df -lh [root@iZ28u0bdecbZ ~]# df -h ...
- VMWare中Centos Minimal最小安装包安装后网络,ftp配置
1.官网下载centos Minimal安装包,安装. 2.使用ip addr命令查看后没有ip地址显示. 3.点击WMWare的编辑->虚拟网络编辑->选择vmnet0(Bridged) ...
- shell脚本判断端口是否打开
[root@www zabbix_scripts]# cat check_httpd.sh #!/bin/bash a=`lsof -i: | wc -l` " ];then " ...
- The window object
At the core of the BOM is the window object, which represents an instance of the browser. The window ...