AOP理解
Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并不是代码方面,更多的是为了项目的模块化,而不仅仅是为了减少重复代码。
AOP是一种编程思想,为的是让模块本身变得更加内聚,让开发者更多的关注到业务逻辑的开发。
在面向切面编程里,把功能分为核心业务功能和周边业务功能:
核心业务,比如登陆,日常增,删数据
周边功能,统计,日志,事务管理。在Spring的面向切面编程AOP思想里,即被定义为切面
在面向切面的思想里,核心业务功能和切面功能单独开发,然后把两个整合在一起,就是AOP。
AOP实现原理
AOP底层将采用代理机制进行实现
接口+实现类:spring采用jdk的动态代理Proxy
实现类:spring采用cglib字节码增强
Spring默认使用JDK动态代理,在需要代理类而不是接口的时候,Spring会自动切换为使用cglib代理,不过现在的项目都是面向接口开发,所以JDK动态代理相对来说用的还是多一些。
Spring AOP引入了几个概念
切面(Aspect),它是跨不同Java类层面的横切性逻辑。可以通过XML文件中配置的普通类,也可以在类代码中使用“@Aspect” 注解去声明,在运行时,Spring会创建类似Advisor来代替它。其内部包括切入和通知。通俗的讲,是要告诉Spring什么时候,什么地方,做什么。
连接点(JoinPoint),程序运行过程中明确的点,一般是方法的调用。
通知(Advice),AOP在特定的切入点上知性的增强处理,告诉Spring什么时候,做什么。一般会讲Advice模拟成一个拦截起,并且在JoinPoint上维护多个Advice,进行层拦截。比如Http鉴权的实现。
切入点(PointCut),就是带有通知的连接点。要切入的对象,可以是类,或方法。在Spring中,所有的方法都可以认为是JoinPoint,都可以添加Advice,但是这并不是所有都是我们真正想要的,而PointCut提供了一组规则,来匹配JointPoint,给满足规则的JointPoint添加Advice。其主要用来修饰JointPoint。
Advice的五种通知类型
前置通知(@Before):在目标方法被调用之前调用通知功能
后置通知(@After):在目标方法完成之后调用通知,此时不会关心方法的输出
返回通知(@After-Returning):在目标方法成功执行之后调用通知
异常通知(@AfterThrowing):在目标方法抛出异常后调用通知
环绕通知(@Around):通知包裹了被通知的方法,在被通知的方法调用之前和之后执行自定义的行为
做个小demo
1. 在src下新建bean包,新建Operator类
package bean; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component; @Component
@Aspect
public class Operator { // @Pointcut("execution(* service.UserService.add()")
// public void service() {
// } @Pointcut("execution(* service.UserService.add())")
public void IService(){ } @Before("IService()")
public void doBefore(JoinPoint joinPoint) {
System.out.println(" before Advice");
} @After("IService()")
public void doAfter(JoinPoint joinPoint) {
System.out.println(" after Advice");
} @AfterReturning(pointcut = "IService()", returning = "returnVal")
public void afterReturn(JoinPoint joinPoint, Object returnVal) {
System.out.println(" after Advice return " + returnVal);
} @AfterThrowing(pointcut = "IService()", throwing = "errors")
public void afterThrowing(JoinPoint joinPoint, Throwable errors) {
System.out.println("afterThrowing Advice ..." + errors);
System.out.println(" afterThrowing..");
} @Around("IService()")
public void doAround(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println(" around Advice before"); try {
proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println(" around Advice before");
}
}
2. src下新建service包,新建UserService类
package service; import org.springframework.stereotype.Service; @Service
public class UserService {
public void add() {
System.out.println("UserService add.");
} public boolean delete() {
System.out.println("UserService delete ..");
return true;
} public void edit() {
System.out.println("UserService edit ");
}
}
3.配置XML文件,在src下新建applicationContext.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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean name="userService" class="service.UserService"></bean>
<bean name="operator" class="bean.Operator"></bean> <aop:config>
<aop:aspect id="operatorAspect" ref="operator">
<aop:pointcut id="servicePointCut" expression="execution(* service.UserService.add())"></aop:pointcut>
<aop:before pointcut-ref="servicePointCut" method="doBefore"></aop:before>
<aop:after pointcut-ref="servicePointCut" method="doAfter"></aop:after>
<aop:around pointcut-ref="servicePointCut" method="doAround"></aop:around>
<aop:after-returning pointcut-ref="servicePointCut" method="afterReturn"
returning="returnVal"></aop:after-returning>
<aop:after-throwing pointcut-ref="servicePointCut" method="afterThrowing"
throwing="errors"></aop:after-throwing>
</aop:aspect>
</aop:config>
</beans>
4.测试AOP,在src下新建test.java
import bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService; public class test {
@Test
public void demo() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) context.getBean("userService", UserService.class);
userService.add();
} }
5.运行结果
Spring学习手札(二)面向切面编程AOP的更多相关文章
-
Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)
一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...
-
spring学习总结二-----面向切面编程(AOP)思想
上一篇spring博客简总结了spring控制反转和依赖注入的相关思想知识点,这篇博文对spring的面向切的编程思想进行简单的梳理和总结. 一.面向切面的思想 与面向对象的纵向关系概念不同,面向切面 ...
-
Spring学习总结之面向切面(AOP)
AOP术语 通知(advice):定义切面是什么以及什么时候使用 连接点(join point):应用在执行过程中能够插入切面的点 切点(pointcut):切点的定义会匹配通知所要织入的一个或多个连 ...
-
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 ...
-
【串线篇】面向切面编程AOP
面向切面编程AOP 描述:将某段代码“动态”的切入到“指定方法”的“指定位置”进行运行的一种编程方式 (其底层就是Java的动态代理)spring对其做了简化书写 场景: 1).AOP加日志保存到数据 ...
-
[译]如何在ASP.NET Core中实现面向切面编程(AOP)
原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...
-
设计模式之面向切面编程AOP
动态的将代码切入到指定的方法.指定位置上的编程思想就是面向切面的编程. 代码只有两种,一种是逻辑代码.另一种是非逻辑代码.逻辑代码就是实现功能的核心代码,非逻辑代码就是处理琐碎事务的代码,比如说获取连 ...
随机推荐
-
LightOJ1283 Shelving Books(DP)
题目 Source http://www.lightoj.com/volume_showproblem.php?problem=1283 Description You are a librarian ...
-
C#堆栈讲解
1:栈就是堆栈,因为堆和堆栈这样说太拗口了,搞得像绕口令,所以有些时候就把堆栈简称为栈.堆和栈,你看这又多舒服.但无论什么时候,堆栈都不等于堆和栈,必须说,堆和栈或者堆和堆栈. 2:值类型变量和引用类 ...
-
spring-data-solr官方学习文档介绍
spring-data-solr文档介绍如下: 通过http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd(spring ...
-
ArcGIS API for Silverlight 编辑Geometry
概述 ArcMap的编辑功能是非常强大的,ArcEngine编写的CS程序也可以用到ArcMap中提供的编辑功能,那么ArcGIS API forSilverlight针对Geometry的编辑提供了 ...
-
android 应用程序记录AAR
@note:接着读赵波的<android NFC开发实例详解>,单独列出这篇文章一是因为上一篇笔记太长了,网页编辑器不太方便编写,二是这部分的知识是android开发中的知识,以后也许会深 ...
-
spark总结
算子总结 1.变换操作,包括过滤,变换,去重,排序,分区操作 filter过滤操作,无法触发重新分区 map,flatMap,flatMapValues,mapValues,mapPartitions ...
-
Elastic Stack之搜索引擎基础
Elastic Stack之搜索引擎基础 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.搜索引擎概述 1>.什么是搜索引擎 搜索引擎(Search Engine)是指根 ...
-
Coursera Deep Learning 3 Structuring Machine Learning Projects, ML Strategy
Why ML stategy 怎么提高预测准确度?有了stategy就知道从哪些地方入手,而不至于找错方向做无用功. Satisficing and Optimizing metric 上图中,run ...
-
jQuery中开发插件的两种方式(附Demo)
做web开发的基本上都会用到jQuery,jQuery插件开发两种方式:一种是类扩展的方式开发插件,jQuery添加新的全局函数(jQuery的全局函数是属于jQuery命名空间的函数),如果将jQu ...
-
ArcGIS Enterprise 10.5.1 静默安装部署记录(Centos 7.2 minimal)- 5、安装Datastore
安装Datastore 解压datastore安装包,tar -xzvf ArcGIS_DataStore_Linux_1051_156441.tar.gz 切换到arcgis账户静默安装server ...