Spring学习记录(五)——初步体验AOP

23人阅读 评论(0) 收藏 举报
分类:

2018.4.16

仅为个人理解 不足之处欢迎指正~

什么是AOP?

以下部分引例参考KenWang的博客~

AOP(Aspect Oriented Programming)——面向切面编程

AOP与IoC是Spring的两大核心思想之一

同样也是对传统的OOP(Object Oriented Programming,面向对象编程)的一种补充

在OOP中 通过继承 多态 封装等概念可以模仿现实生活中的各种纵向关系

但OOP并不适用于模仿横向关系

什么是横向关系?

想象几个实际生活中的例子:

1.在操作ATM时我们可能进行如下操作:

  •    取款: 开始——输入密码——取款——结束
  •    转账: 开始——输入密码——转账——结束
  •    余额: 开始——输入密码——查询——结束

在这个例子中我们可以看到 如果我们将 取款 转账 查询余额 作为核心操作

那么输入密码这一操作就是被核心操作所调用的“辅助操作

这一形容并不是说辅助操作的重要性低 而是相对于各有所专的核心操作而言

辅助操作显得重复且无关

2.在一个购物系统中 可能需要进行以下操作:

  • 对生成的每一笔订单提供事务管理
  • 当用户点击、搜索某关键字时 我们想要统计这类商品的点击率
  • 当用户登录、退出、修改密码时 我们需要记录进行操作的地点与时间

这个例子中的三项操作 均可以看作是核心业务功能的“辅助功能

这与 “切面” “横向关系” 又怎么理解?



我们可以看到 在ATM例子中 我们将取款 转账 查询余额三个互不相关的业务画作三条直线

而这三个业务都需要 输入密码 这一辅助功能的支持

而这条切入于三条黑线的红线 就是所谓的“切面

红线与黑线的交点 可以称为“切点

同时 也建立起了“横向关系

在面向切面编程AOP的思想中

让核心业务功能和切面功能分别独立开发

然后再将这两者编织在一起 这就叫做AOP



为什么要使用AOP?

与Spring的另一核心思想IoC一样 AOP同样致力于使代码更加简洁明了 让我们将心思更多的花在核心代码的构建中

假如在ATM例子中

取款、转账、查询余额为三个不同的服务

现在这三个服务都需要“验证身份”这一功能的支持

那么该怎么做?

或许你会想到 在这三段代码中都加入一段验证身份的代码

或许你会想到 写一个单独的函数 然后在三个服务开始时调用它

但是这些方法都会产生代码的重复及耦合

总之:

AOP可以使业务模块更简洁 并解决业务逻辑与辅助模块的耦合度问题


开始使用AOP

额外添加的包:


其他Spring需要包与之前内容相同


我们使用这样一个例子:

现在有一个登录服务 我们需要在登录的前后打印系统时间

我们将登录服务作为核心业务 将打印时间作为辅助业务

首先构建项目结构:


在aspect包中编写Timeprint类:

package com.tzy.aspect;

public class Timeprint 
{
	public void printTime()
	{
		System.out.println("当前时间为:"+System.currentTimeMillis());
	}
}

在serive包中编写Login类:

package com.tzy.serive;

import java.util.Scanner;

public class Login 
{
	public void log()
	{
		Scanner sc=new Scanner(System.in);
		System.out.println("请输入用户名:");
		String username=sc.next();
		System.out.println(username+"  登录成功!");
	}
}

编写测试类:

package com.tzy.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tzy.serive.Login;

public class testAOP 
{
	public static void main(String args[])
	{
		ApplicationContext context=new ClassPathXmlApplicationContext
				(new String[]{"applicationContext.xml"});
		Login user1=(Login)context.getBean("login");
		user1.log();
	}
}

现在配置applicationContext:

<?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:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
   http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop 
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx 
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context      
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">
   <context:annotation-config/>
      
   <bean name="login" class="com.tzy.serive.Login" >
   </bean>
    <bean id="Timeprint" class="com.tzy.aspect.Timeprint">
   </bean>
   
   <aop:config>
   		<aop:aspect id="time" ref="Timeprint">
   				<aop:pointcut id="test1" 
   				expression="execution(* com.tzy.serive.Login.*(..))"/>
   				<aop:before method="printTime" pointcut-ref="test1"/>
   				<aop:after method="printTime" pointcut-ref="test1"/>
   		</aop:aspect>
   </aop:config>
	
  </beans>

运行:



接下来解释一下配置文件中的部分问题

1.bean类的装配请参考前面的文章


2.<aop:aspect>


当切面代码是自动注入的bean时 使用ref属性可直接使用

在上面我们可以看到对Timerprint类的注入:



3.<aop:pointcut>与execution

pointcut表示建立一个切点

execution则比较复杂

在这里先用execution(* *.*(..))代替

第一个出现的*表示:对任意的返回类型方法进行匹配 可以改为void int double之类以匹配特定返回类型函数

第二个出现的*表示:全类名

第三个出现的*表示:对任意的方法名进行匹配

最后出现的(..)表示:匹配任意类型、数量的参数 


4.<aop before>及其他

何时执行切面代码是需要我们进行配置的 比如在核心业务调用之前或者之后

一共有如下几种类型:


  • after 在方法完成之后调用通知 无论其是否执行成功
  • after-returning 在方法成功执行之后调用
  • after-throwing 在方法抛出异常之后调用
  • around 在之前与之后调用
  • before 在方法调用之前调用通知

5.method


如图 我们在之前的测试中均调用的是printTime方法 这是切面类中的某个方法

现在我们在切面类中加上一个方法:


此时修改method为:


运行测试类:


可以看到调用的通知函数不同


总结:

以上就是AOP的简单用法

以后会补充使用注解进行AOP的操作

另外需要注意的是Spring只支持方法连接点 只有在调用某个方法时 才能构建切入点


谢谢~

查看评论

Spring AOP实践--记录类方法执行时间

网上有许多关于记录方法执行时间的帖子,但是看了一下,基本上操作不方便,或者都是开发测试性质的不太适用,我在这里做了完善,直接内置到项目中,使用的时候只需要在方法上添加注解@MethodLog即可,非常...
  • junehappylove
  • junehappylove
  • 2016-12-09 15:51:21
  • 1953

spring aop记录操作日志和错误日志

AOP介绍aop这个概念不陌生了,我们就结合下边这个图来简单的介绍一下aop中的几个概念。 AOP:Aspect-Oriented Programming的缩写 JoinPoint:要切入的点...
  • lovemenghaibin
  • lovemenghaibin
  • 2016-06-03 21:38:10
  • 4852

SpringAOP注解方式记录操作日志(操作模块,操作功能,调用方法,主键信息等)支持多笔操作时记录

使用AOP切入的方式记录操作日志,本代码主要采用枚举作为记录方式,具体代码如下. 首先先定义先关枚举: /** * 枚举公共接口 * @author LeiYong * */ public i...
  • leiyong0326
  • leiyong0326
  • 2016-07-26 20:11:22
  • 1109

Spring AOP实现复杂的日志记录(自定义注解)

前段时间做项目中,业务逻辑要求只要对数据库数据进行改动的都需要记录日志(增删改),记录的内容有操作者,操作的表名及表名称,具体的操作,以及对那条数据进行操作。当时想到的就是Spring 的AOP功能。...
  • mlc1218559742
  • mlc1218559742
  • 2016-06-28 19:37:22
  • 11502

spring框架学习(六)AOP

AOP(Aspect-OrientedProgramming)面向方面编程,与OOP完全不同,使用AOP编程系统被分为方面或关注点,而不是OOP中的对象。    AOP的引入  在OOP面向对象的使用...
  • lishuangzhe7047
  • lishuangzhe7047
  • 2014-03-15 23:36:26
  • 52185

Spring AOP实现日志记录

在很多时候,我们都需要将一些关键的日志信息保存到数据库中,而此时Spring aop能够较灵活的解决这一问题,并不带有侵入性。关于spring aop的介绍,网上有不少文章进行介绍,在这里就略去这一点...
  • CXC0716
  • CXC0716
  • 2015-03-27 10:25:24
  • 1961

Spring学习总结——Spring实现AOP的多种方式

 目录 一、基于XML配置的Spring AOP二、使用注解配置AOP三、AspectJ切点函数四、AspectJ通知注解五、零配置实现Spring IoC与AOP六、示例下载 ...
  • u010987379
  • u010987379
  • 2016-08-08 16:13:26
  • 36526

从头认识Spring-3.2 简单的AOP日志实现-需要记录方法的运行时间

上一章节我们只是在做蛋糕的前后记录了一下日志,这个不够,我们需要记录做蛋糕需要的时间,这里就需要引入标签。1.domain蛋糕类:package com.raylee.my_new_spring.my...
  • raylee2007
  • raylee2007
  • 2016-02-21 23:05:18
  • 1783

spring boot aop 记录方法执行时间

前言 为了性能调优,需要先统计出来每个方法的执行时间,直接在方法前后log输出太麻烦,可以用AOP来加入时间统计 添加依赖 dependency> groupId>org.sp...
  • joshua1830
  • joshua1830
  • 2017-01-12 09:35:39
  • 3274

Spring AOP控制日志管理对修改字段比较提取插入

本程序代码是基于ssh的   1 。 基于接口编程创建一个日志接口 package com.osnt.dao.recordLog; import java.io.Serializable;...
  • alongshow
  • alongshow
  • 2012-04-13 11:34:53
  • 1250
    个人资料
    等级:
    访问量: 41
    积分: 73
    排名: 122万+
    文章存档
    最新评论