Java Spring AOP用法
Java Spring AOP用法
Spring AOP
Java web 环境搭建
Java web 项目搭建
Java Spring IOC用法
spring提供了两个核心功能,一个是IoC(控制反转),另外一个便是Aop(面向切面编程),IoC有助于应用对象之间的解耦,AOP则可以实现横切关注点(如日志、安全、缓存和事务管理)与他们所影响的对象之间的解耦。
1.简介
AOP主要包含了通知、切点和连接点等术语,介绍如下
- 通知(Advice)
通知定义了切面是什么以及何时调用,何时调用包含以下几种
Before 在方法被调用之前调用通知
After 在方法完成之后调用通知,无论方法执行是否成功
After-returning 在方法成功执行之后调用通知
After-throwing 在方法抛出异常后调用通知
Around 通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
切点(PointCut)
通知定义了切面的什么和何时,切点定义了何处,切点的定义会匹配通知所要织入的一个或多个连接点,我们通常使用明确的类的方法名称来指定这些切点,或是利用正则表达式定义匹配的类和方法名称来指定这些切点。
切点的格式如下execution(* com.ganji.demo.service.user.UserService.GetDemoUser (..) )
连接点(JoinPoint)
连接点是在应用执行过程中能够插入切面的一个点,这个点可以是调用方法时,抛出异常时,甚至是修改一个字段时,切面代码可以利用这些连接点插入到应用的正常流程中,并添加新的行为,如日志、安全、事务、缓存等。
现阶段的AOP框架
AOP框架除了Spring AOP之外,还包括AspectJ、JBoss AOP;
上述框架的区别是Spring AOP只支持到方法连接点,另外两个还支持字段和构造器连接点。
2.用法
同依赖注入一样,AOP在spring中有两种配置方式,一是xml配置的方式,二是自动注解的模式。
2.1 xml中声明切面
- 2.1.1 AOP配置元素
在xml中,我们使用如下AOP配置元素声明切面
AOP配置元素 | 描述
------------ | -------------
`<aop:advisor>` | 定义AOP通知器
`<aop:after>` | 定义AOP后置通知(不管该方法是否执行成功)
`<aop:after-returning>` | 在方法成功执行后调用通知
`<aop:after-throwing>` | 在方法抛出异常后调用通知
`<aop:around>` | 定义AOP环绕通知
`<aop:aspect>` | 定义切面
`<aop:aspect-autoproxy>` | 定义`@AspectJ`注解驱动的切面
`<aop:before>` | 定义AOP前置通知
`<aop:config>` | 顶层的AOP配置元素,大多数的<aop:*>包含在<aop:config>元素内
`<aop:declare-parent>` | 为被通知的对象引入额外的接口,并透明的实现
`<aop:pointcut>` | 定义切点
- 2.1.2 定义切面
我们在service层添加
com.ganji.demo.service.aspect.XmlAopDemoUserLog
类,里面实现了拦截方法,具体如下
package com.ganji.demo.service.aspect; import org.aspectj.lang.ProceedingJoinPoint; /**
* Created by admin on 2015/9/2.
*/
public class XmlAopDemoUserLog {
// 方法执行前通知
public void beforeLog() {
System.out.println("开始执行前置通知 日志记录");
}
// 方法执行完后通知
public void afterLog() {
System.out.println("开始执行后置通知 日志记录");
}
// 执行成功后通知
public void afterReturningLog() {
System.out.println("方法成功执行后通知 日志记录");
}
// 抛出异常后通知
public void afterThrowingLog() {
System.out.println("方法抛出异常后执行通知 日志记录");
} // 环绕通知
public Object aroundLog(ProceedingJoinPoint joinpoint) {
Object result = null;
try {
System.out.println("环绕通知开始 日志记录");
long start = System.currentTimeMillis(); //有返回参数 则需返回值
result = joinpoint.proceed(); long end = System.currentTimeMillis();
System.out.println("总共执行时长" + (end - start) + " 毫秒");
System.out.println("环绕通知结束 日志记录");
} catch (Throwable t) {
System.out.println("出现错误");
}
return result;
}
}- 2.1.3 xml声明切面并调用
我们在web层,
web-inf/dispatcher-servlet.xml
中定义切面,具体如下
<!--定义切面 指定拦截方法时 做什么-->
<bean id="xmlAopDemoUserLog" class="com.ganji.demo.service.aspect.XmlAopDemoUserLog"></bean>
<aop:config>
<aop:aspect ref="xmlAopDemoUserLog"> <!--指定切面-->
<!--定义切点-->
<aop:pointcut id="logpoint" expression="execution(* com.ganji.demo.service.user.UserService.GetDemoUser(..))"></aop:pointcut>
<!--定义连接点-->
<aop:before pointcut-ref="logpoint" method="beforeLog"></aop:before>
<aop:after pointcut-ref="logpoint" method="afterLog"></aop:after>
<aop:after-returning pointcut-ref="logpoint" method="afterReturningLog"></aop:after-returning>
<aop:after-throwing pointcut-ref="logpoint" method="afterThrowingLog"></aop:after-throwing>
</aop:aspect>
</aop:config>在controller下调用,调用具体如下
DemoUserEntity demoUser=userService.GetDemoUser(1);
这是运行起来 我们将看到打印出如下日志
开始执行前置通知 日志记录
开始执行后置通知 日志记录
方法成功执行后通知 日志记录- 2.1.4 小结
如果通过xml配置,我们还可以实现环绕通知,环绕通知的目的是把前置通知和后置通知的信息共享起来。同时还可以为通知传递方法的参数,在切面拦截中验证参数的有效性。
2.2 自动注解AOP
在上述2.1中我们通过xml配置的形式 实现了AOP编程,现在我们通过不配置xml,配置注解的形式实现AOP。
- 2.2.1 配置自动代理
使用配置注解,首先我们要将切面在spring上下文中声明成自动代理bean,我们需要在web层的
web-inf/dispatcher-servlet.xml
文件中配置如下一句话即可<aop:aspectj-autoproxy />
当然我们需要在xml的根目录beans下引用aop的命名空间和xsi
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"- 2.2.2 使用
@Aspect
注解
声明一个切面,只需要在类名上添加
@Aspect
属性即可,具体的连接点,我们用@Pointcut
和@Before
、@After
等标注。具体如下
在声明前 我们需要依赖配置pom
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>声明切面类,包含了注解
@Aspect
以及何时(如@Before
)执行通知
package com.ganji.demo.service.aspect; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Service; /**
* Created by admin on 2015/9/2.
*/
@Aspect
@Service
public class XmlAopDemoUserLog { // 配置切点 及要传的参数
@Pointcut("execution(* com.ganji.demo.service.user.UserService.GetDemoUser(..)) && args(id)")
public void pointCut(int id)
{ } // 配置连接点 方法开始执行时通知
@Before("pointCut(id)")
public void beforeLog(int id) {
System.out.println("开始执行前置通知 日志记录:"+id);
}
// 方法执行完后通知
@After("pointCut(id)")
public void afterLog(int id) {
System.out.println("开始执行后置通知 日志记录:"+id);
}
// 执行成功后通知
@AfterReturning("pointCut(id)")
public void afterReturningLog(int id) {
System.out.println("方法成功执行后通知 日志记录:"+id);
}
// 抛出异常后通知
@AfterThrowing("pointCut(id)")
public void afterThrowingLog(int id) {
System.out.println("方法抛出异常后执行通知 日志记录"+id);
} // 环绕通知
@Around("pointCut(id)")
public Object aroundLog(ProceedingJoinPoint joinpoint,int id) {
Object result = null;
try {
System.out.println("环绕通知开始 日志记录"+id);
long start = System.currentTimeMillis(); //有返回参数 则需返回值
result = joinpoint.proceed(); long end = System.currentTimeMillis();
System.out.println("总共执行时长" + (end - start) + " 毫秒");
System.out.println("环绕通知结束 日志记录");
} catch (Throwable t) {
System.out.println("出现错误");
}
return result;
}
}- 2.2.3 总结
按照上述两个步骤,使用注解实现Aop即可,这里依赖了IOC。
Java Spring AOP用法的更多相关文章
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- Java Spring IOC用法
Java Spring IOC用法 Spring IoC 在前两篇文章中,我们讲了java web环境搭建 和 java web项目搭建,现在看下spring ioc在java中的运用,开发工具为In ...
- 【转】Java Spring AOP详解
一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnbl ...
- 从零开始学 Java - Spring AOP 拦截器的基本实现
一个程序猿在梦中解决的 Bug 没有人是不做梦的,在所有梦的排行中,白日梦最令人伤感.不知道身为程序猿的大家,有没有睡了一觉,然后在梦中把睡之前代码中怎么也搞不定的 Bug 给解决的经历?反正我是有过 ...
- Java - Spring AOP 拦截器的基本实现
一个程序猿在梦中解决的 Bug 没有人是不做梦的,在所有梦的排行中,白日梦最令人伤感.不知道身为程序猿的大家,有没有睡了一觉,然后在梦中把睡之前代码中怎么也搞不定的 Bug 给解决的经历?反正我是有过 ...
- Spring AOP 用法浅谈(Day_18)
当你这一天没有在进步,那你就是在退步! [简述] Aspect Oriented Programming :面向切面编程 所谓面向切面编程,是一种通过预编译和运行期动态代理的方式实现在不修改源代码的情 ...
- 最全的Spring AOP
1.什么是AOP? AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, ...
- Java缓存框架使用EhCache结合Spring AOP
一.Ehcache简介 EhCache是一个纯Java的进程内缓存框架,具有如下特点: 1. 快速简单,非常容易和应用集成. 2.支持多种缓存策略 . 3. 缓存数据有 ...
随机推荐
- transform-style: preserve-3d在iphone下的bug
经测,当元素设置transform-style: preserve-3d;后,其实现rotateY时的动画效果会穿透上层的覆盖图层. 马克一下
- Flask备注三(Context)
Flask备注三(Context) Flask支持不同的应用场景下,对应不同的local context(本地上下文环境),用来提供当前环境下的资源.lcoal context和全局变量以及局部变量最 ...
- 《笨办法学C》笔记之指针
C语言编程主要操作的对象就是指针. 指针从哪里来 指针就是表示内存存储区域的一组数值,使用%p格式化字符串. Linux系统会为程序维护两个临时变量存储位置:栈.堆.栈的空间少,栈通常在用户更高的地址 ...
- jenkins自动部署maven工程到服务器----SSH+shell
今天心情不是很美丽,玩笑话可能没那么多,还是回归正题 1.指定SSH端口.用户名.密码相关配置,我这里没有需要配置密钥啥的. 2.接下来再创建任务的时候,进行SSH配置: 3.看到这里,是不是很想打我 ...
- sublime text3 less2css rem
1.下载sublime text3 官网地址:https://www.baidu.com/link?url=2kr0ijQXVL1_6oXdPByYh7ecMl7OUAYVx5fyTNjMrYVdtq ...
- C#之不借助第三变量交换两变量值
源码: 1 2 3 4 5 int n1=10, n2=20; n1 = n1 - n2; // -10 n2 = n1 + n2; // 10 n1 = n2 - n1 ...
- 【转】 71道经典Android面试题和答案,重要知识点都包含了
,,面试题1. 下列哪些语句关于内存回收的说明是正确的? (b ) A. 程序员必须创建一个线程来释放内存 B.内存回收程序负责释放无用内存 C.内存回收程序允许程序员直接释放内存 ...
- 【日常小问题】windows系统操作技巧
如何将文件夹视图设置为“详细信息” @2015.3.30 这段时间刚换了电脑,资源管理器视图模式为“大图标”,很不符合俺的操作习惯.修改之—— 1.打开一个文件夹,设置为详细信息显示. 2.点击工具- ...
- 完全用CSS实现的表格
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- web应用程序传递连接字符串给FastReport数据源
public static FastReport.Report fr = new FastReport.Report(); public static FastReport.EnvironmentSe ...