Spring 面向切面编程(AOP)
Spring 系列教程
- Spring 框架介绍
- Spring 框架模块
- Spring开发环境搭建(Eclipse)
- 创建一个简单的Spring应用
- Spring 控制反转容器(Inversion of Control – IOC)
- 理解依赖注入(DI – Dependency Injection)
- Bean XML 配置(1)- 通过XML配置加载Bean
- Bean XML 配置(2)- Bean作用域与生命周期回调方法配置
- Bean XML 配置(3)- 依赖注入配置
- Bean XML 配置(4)- 自动装配
- Bean 注解(Annotation)配置(1)- 通过注解加载Bean
- Bean 注解(Annotation)配置(2)- Bean作用域与生命周期回调方法配置
- Bean 注解(Annotation)配置(3)- 依赖注入配置
- Bean Java配置
- Spring 面向切面编程(AOP)
- Spring 事件(1)- 内置事件
- Spring 事件(2)- 自定义事件
面向切面编程(Aspect Oriented Programming/AOP)是Spring框架核心技术之一。
面向切面编程的主要作用是,在不修改源代码的情况下,可以给目标类打补丁,让其执行补丁中的代码。
例如,用户类中有个登录方法,现在需要加用户登录日志。使用AOP就不需要修改用户登录方法,只需把日志代码注入到用户登录方法前后,让其执行。日志代码就是“切面”,插入代码的地方(用户类的登录方法)就是“连接点”。
面向切面编程概念
先介绍一些AOP的概念
- 切面(Aspect) - 一些横跨多个类的公共模块,如日志、安全、事务等。简单地说,日志模块就是一个切面。
- 连接点(Joint Point) - 目标类中插入代码的地方。连接点可以是方法、异常、字段,连接点处的切面代码会在方法执行、异常抛出、字段修改时触发执行。
- 建议(Advice) - 在连接点插入的实际代码(即切面的方法),有5种不同类型(后面介绍)。
- 切点(Pointcut) - 定义了连接点的条件,一般通过正则表达式。例如,可以定义所有以
loadUser
开头的方法作为连接点,插入日志代码。
建议类型
- before - 在方法之前运行建议(插入的代码)
- after - 不管方法是否成功执行,在方法之后运行插入建议(插入的代码)
- after-returning - 当方法执行成功,在方法之后运行建议(插入的代码)
- after-throwing - 仅在方法抛出异常后运行建议(插入的代码)
- around - 在方法被调用之前和之后运行建议(插入的代码)
实现
与Bean配置一样,切面也需要配置,然后由Spring容器加载。切面配置可以使用XML,或者使用“AspectJ”语法,“AspectJ”语法使用Java代码实现切面配置。
为更深理解AOP,下面实现一个日志切面的例子,例子使用XML配置。
User类
一个简单的用户类,是日志切面插入的目标类。用户类实现了几个不同的方法,这些方法会作为连接点。
User.java
public class User {
private Integer id;
private String name;
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
System.out.println("Id: " + id);
return id;
}
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();
}
}
切面 - Logging
日志切面类,定义了要插入目标类执行的方法。
Logging.java
public class Logging {
public void beforeAdvice(){
System.out.println("Before Advice");
}
public void afterAdvice(){
System.out.println("After Advice");
}
public void afterReturningAdvice(Object retVal){
System.out.println("After Advice Executed Successfully ... Returning: " + retVal.toString() );
}
public void AfterThrowingAdvice(IllegalArgumentException ex){
System.out.println("There has been an exception when executing the advice: " + ex.toString());
}
}
retVal是目标类连接点(方法)返回的值。例如,如果连接点是User类的getName()
方法,该方法返回用户名称,那么retVal
将被赋值用户名称。
配置
本例使用XML配置切面。
首先定义切面类的Bean,然后切面定义中引用该Bean。
切面定义中,会指明切点、插入的代码(建议),以及插入的代码怎么执行(建议类型)。
下面的示例定义了一个名为UserAllMethod
的切点,使用expression="execution(* User.*(..))"
匹配User类中的所有方法作为连接点。
如果想指定特定方法作为连接点,可使用
execution(* User.getName(..))
。
**示例: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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:config>
<!-- Aspect -->
<aop:aspect id="loggingAspect" ref="logging">
<!-- Pointcut -->
<aop:pointcut id="UserAllMethods" expression="execution(* User.*(..))"/>
<!-- Advice(s) -->
<aop:before pointcut-ref="UserAllMethods" method="beforeAdvice"/>
<aop:after pointcut-ref="UserAllMethods" method="afterAdvice"/>
<aop:after-returning pointcut-ref="UserAllMethods" returning="retVal" method="afterReturningAdvice"/>
<aop:after-throwing pointcut-ref="UserAllMethods" throwing="ex" method="AfterThrowingAdvice"/>
</aop:aspect>
</aop:config>
<!-- The user bean -->
<bean id="user" class="User">
<property name="name" value="隔壁老王" />
<property name="id" value="99"/>
</bean>
<!-- logging 切面定义 -->
<bean id="logging" class="Logging"/>
</beans>
确保已经添加了依赖的JAR包,我们使用Maven,pom.xml
中添加依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
测试切面
在main类中调用用户类的方法,查看切面是否被执行:
Test.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User user = (User) context.getBean("user");
user.getName();
user.printThrowException();
}
}
Spring 面向切面编程(AOP)的更多相关文章
- Spring面向切面编程(AOP)
1 spring容器中bean特性 Spring容器的javabean对象默认是单例的. 通过在xml文件中,配置可以使用某些对象为多列. Spring容器中的javabean对象默认是立即加载(立即 ...
- Spring面向切面编程(AOP,Aspect Oriented Programming)
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- Spring面向切面编程(AOP)方式二
使用注解进行实现:减少xml文件的配置. 1 建立切面类 不需要实现任何特定接口,按照需要自己定义通知. package org.guangsoft.utils; import java.util.D ...
- Spring面向切面编程AOP(around)实战
spring aop的环绕通知around功能强大,我们这里就不细说,直接上代码,看着注释就能明白 需要的可以点击下载源码 1.如果使用注解的方式则需要先创建个注解类 package com.mb.a ...
- Spring学习手札(二)面向切面编程AOP
AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...
- Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)
一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...
- Spring框架学习笔记(2)——面向切面编程AOP
介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...
- Spring之控制反转——IoC、面向切面编程——AOP
控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...
- 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制
spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...
随机推荐
- win7/10获取本地wifi密码明文
win7 单击右下角无线网图标,选择已连接的无线网 右击无线网名称,选择属性 点击标题栏的安全,再点击显示字符,即可显示wifi密码明文 win10 控制面板[查看方式选类别]-查看网络状态和任务 点 ...
- 【转】stm32 IAP升级程序
一.什么是IAP,为什么要IAP IAP即为In Application Programming(在应用中编程),一般情况下,以STM32F10x系列芯片为主控制器的设备在出厂时就已经 ...
- spingboot中使用scheduled设置定时任务注意事项
在spring开发过程中经常会遇到需要定时执行的任务,如定时生成报表,定时推送消息等任务. springboot 提供了简单的 @Scheduled 表达式来配置定时任务.该方式默认是单线程的,任务在 ...
- OSX10.10 Yosemite安装Metasploit
安装环境 操作时间: 2015/6/8 操作系统: OSX Yosemite 10.10.3 Metasploit版本: v4.11.0-dev [core:4.11.0.pre.dev api:1. ...
- 物联网学习笔记——构建RESTFul平台1
0.前言 前些时间顺着Yeelink学习了RESTFUL,使用PHP和Slim框架尝试实现简单的REST API,树莓派可通过GET方法获得JSON数据包,通过这种方式实现了树莓派和服务器(我 ...
- 十八 JQuery&Ajax&Json&Xstream
JQuery 1 是什么?有什么用? JavaScript的代码类库 简化代码,提高效率.write less do more 1 JQuery与Servlet数据交互,load方式(少用) 语法:$ ...
- 在ListView头和尾添加东西
直接上代码 import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view ...
- 继OpenJDK 之后,OpenJFX也将迁移到 Git
导读 近日 OpenJFX 项目负责人 Kevin Rushforth 提交了一份将 OpenJFX 迁移到 GitHub 的提案. OpenJFX 是 JavaFX 的开源实现.JavaFX 是一个 ...
- QT5安装
Windows+Qt5.3.1+VS2013安装教程 https://blog.csdn.net/two_ye/article/details/96109876 (已成功)windows下,VS201 ...
- 编程练习:实现树的层次遍历 (CVTE笔试)
直接层次遍历是比较简单的,但是题目要求的分层打印,这就变得稍微有些麻烦 我是采用两个队列的方法实现. 1.将树结构入队列1. 2.当队列1和队列2都不为空的时候,则一直循环. 3.当队列1不为空的时候 ...