Spring学习之AOP的三种实现方式

一、介绍AOP

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

需要了解一下名词:

  • 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....
  • 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
  • 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
  • 目标(Target):被通知对象。
  • 代理(Proxy):向目标对象应用通知之后创建的对象。
  • 切入点(PointCut):切面通知 执行的 “地点”的定义。
  • 连接点(JointPoint):与切入点匹配的执行点。

简单来说就是不改变原来代码的情况下增加新功能的方式。

二、三种实现方式

设定通过在具体的业务实现方法前后增加输出日志的功能来实现AOP的功能

首先需要导入依赖包

<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>

第一种通过 Spring API 实现

首先编写业务接口和实现类

public interface UserService {
void add();
void delete();
void update();
void select();
}
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("增加了一个用户!");
} @Override
public void delete() {
System.out.println("删除了一个用户!");
} @Override
public void update() {
System.out.println("更新了一个用户!");
} @Override
public void select() {
System.out.println("查询了一个用户!");
}
}

编写两个打印日志的实现类

一个是实现API的 MethodBeforeAdvice 方法,实现执行方法之前的日志输出

import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method; public class BeforeLog implements MethodBeforeAdvice {
// method:要执行目标对象的方法
// args:参数
// target:目标对象
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
}
}

另一个是API的 AfterReturningAdvice 方法,实现执行方法之后的日志输出

import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method; public class AfterLog implements AfterReturningAdvice {
// returnValue:返回值
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了"+method.getName()+"的方法,返回结果为:"+returnValue);
}
}

然后去applicationContext.xml配置文件中注册bean以及配置切入方式

<!--方式一:使用spring原生API接口-->
<!--注册bean-->
<bean id="userService" class="com.tioxy.service.UserServiceImpl"/>
<bean id="afterLog" class="com.tioxy.log.AfterLog"/>
<bean id="beforeLog" class="com.tioxy.log.BeforeLog"/>
<!--配置AOP-->
<aop:config>
<!--切入点:就是在哪里执行方法
expression:表达式
execution(要执行的位置)
-->
<aop:pointcut id="pointcut" expression="execution(* com.tioxy.service.UserServiceImpl.*(..))"/> <!--执行环绕增强-->
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
</aop:config>

最后进行测试

public class Mytest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.add(); }
}

第二种自定义类来实现Aop

业务接口和实现类还是 UserService 和 UserServiceImpl

编写自定义实现类

public class DiyPointCut {
public void before(){
System.out.println("=============方法执行前============");
} public void after(){
System.out.println("=============方法执行后============");
}
}

然后去applicationContext.xml配置文件中注册bean以及配置切入方式

<!--第二种方式自定义实现-->
<!--注册bean-->
<bean id="diy" class="com.kuang.config.DiyPointcut"/> <!--aop的配置-->
<aop:config>
<!--第二种方式:使用AOP的标签实现-->
<aop:aspect ref="diy">
<aop:pointcut id="diyPonitcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
<aop:before pointcut-ref="diyPonitcut" method="before"/>
<aop:after pointcut-ref="diyPonitcut" method="after"/>
</aop:aspect>
</aop:config>

然后进行测试

public class Mytest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.add(); }
}

第三种使用注解方式实现Aop

编写一个注解方式的实现类

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; @Aspect
public class AnnotationPointcut {
@Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("---------方法执行前---------");
} @After("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("---------方法执行后---------");
}
}

然后去applicationContext.xml配置文件中注册bean以及配置切入方式

<!--方式三:使用注解-->
<bean id="annotationPointCut" class="com.tioxy.diy.AnnotationPointCut"/>
<!--开启注解支持-->
<aop:aspectj-autoproxy/>

最后进行测试

以上就是AOP的三种实现方式

文章引用

狂神说Java:https://www.bilibili.com/video/BV1WE411d7Dv?p=20

Spring学习之AOP的实现方式的更多相关文章

  1. spring 学习之 bean 的注入方式 property和constructor-arg的使用方式

    spring 学习之 bean 的注入方式 property和constructor-arg的使用方式. bean的注入方式: property 注入是: 通过setxx方法注入. construct ...

  2. Spring学习之AOP总结帖

    AOP(面向方面编程),也可称为面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP). 在进行 OOP 开发时,都是基于对组件(比如类)进行开发,然后对组件进行组 ...

  3. spring学习(二) ———— AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  4. spring学习(六)注解方式实现AOP

    一.导包(导入maven的依赖) <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...

  5. Spring学习之AOP

    Spring-AOP(Aspect-orented programming) 在业务流程中插入与业务无关的逻辑,这样的逻辑称为Cross-cutting concerns,将Crossing-cutt ...

  6. Spring学习之Aop的各种增强方法

    AspectJ允许使用注解用于定义切面.切入点和增强处理,而Spring框架则可以识别并根据这些注解来生成AOP代理.Spring只是使用了和AspectJ 5一样的注解,但并没有使用AspectJ的 ...

  7. Spring学习之Aop的基本概念

    转自:http://my.oschina.net/itblog/blog/209067 AOP的基本概念 AOP从运行的角度考虑程序的流程,提取业务处理过程的切面.AOP面向的是程序运行中的各个步骤, ...

  8. Spring学习之AOP与事务

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

  9. spring学习笔记-AOP

    1.aop:aspect oriented programming 面向切面编程 2.aop在spring中的作用:   提供声明式服务(声明式事务) 允许用户实现自定义切面 3.aop:在不改变原有 ...

随机推荐

  1. python之浅谈编程语言

    一.编程语言的分类 机器语言(低级语言) 可以直接和硬件交互,用0和1和计算机沟通 优点:执行效率高(因为可以直接和计算机沟通) 缺点:开发效率低(都是用0和1进行编码) 汇编语言 同样可以直接和硬件 ...

  2. Spring笔记(3) - debug源码AOP原理解析

    案例 @EnableAspectJAutoProxy//开启基于注解的aop模式 @Configuration public class AOPConfig { //业务逻辑类加入容器中 @Bean ...

  3. A*算法求K短路模板 POJ 2449

    #include<cstdio> #include<queue> #include<cstring> using namespace std; const int ...

  4. SQL批量插入数据【万级】

    1.每4000条插入一次 for (int i = 0; i < dt.Rows.Count; i++) { IsTBProductForStockInfo model = new IsTBPr ...

  5. CRLF injection 简单总结

    CRLF injection 简单总结 简介 CRLF是"回车 + 换行"(\r\n)的简称,即我们都知道在HTTP协议中,HTTP Header与HTTP Body是用两个CRL ...

  6. nuxt.js使用scss

    1>安装一些loader npm i node-sass sass-loader scss-loader --save-dev 2>在nuxt.config.js中配置(需要全局使用的sc ...

  7. 纯js实现日期选取功能

    平年: 2月-->28天 4,6,9,11月-->30天 1,3,5,7,8,10,12月-->31天 闰年: 2月-->29天 4,6,9,11月-->30天 1,3, ...

  8. python数据处理(六)之数据清洗:标准化和脚本化

    1.数据归一化和标准化 a. 归一化:对数据集进行计算,使数据都位于一个特定的范围\ b.标准化: c.删除离群值 2.数据存储 a.保存到SQLite数据库中 b.导出到简单的文件中csv 3.找到 ...

  9. Visual SVN Server+TortoiseSVN进行源代码管理

    安装VisualSVN Server 安装完之后,可配置SVN Server的IP地址,右键下图红色部分,选择属性,然后可配置ServeName和IP Address 之后可以创建用户.用户组和项目库 ...

  10. 【Python学习笔记一】基础环境安装:idea+python

    IDEA 安装 1.下载IDEA   官网下载地址: https://www.jetbrains.com/idea/ 2.安装的时候配置基本选择默认配置就行 参考链接:https://blog.csd ...