AOP与OOP概念

OOP(Object Oriented Programming,面向对象编程),通过封装、继承将程序抽象为各个层次的对象,进而组合为模块或者程序,达到了软件工程中的重用性、灵活性、扩展性。程序的运行笼统地可以看为各层次对象之间的相互调用。
AOP(Aspect Oriented Programming,面向切面编程),将程序运行过程分解为一个个的切面,对特定的切面(某个步骤或者阶段)进行提取,达到解耦各种不同逻辑代码。

OOP是在程序分块层面上进行考虑,而AOP则是在程序运行的切面上进行考虑。

AOP使用

xml的使用方式

1.使用步骤(1)环境搭建,注意:导入aspectjweaver-1.9.5.jar(2)创建业务类、切面类(3)创建配置文件,并配置切面信息:以上涉及到的类必须纳入到Spring IOC容器管理(4)测试
2.记忆的点2.1切点的声明:标签、表达式2.2通知:前置通知、后置通知、返回通知、异常通知、环绕通知(!joinPoint.proceed())

注解的使用方式

1.使用步骤(1)环境搭建,注意:导入aspectjweaver-1.9.5.jar(2)创建业务类、切面类(定义了切面所有的东西)(3)开启包扫描、开启切面编程(4)测试
2.记忆的点2.1切点的声明:注解、表达式、声明在方法上2.2通知:前置通知、后置通知、返回通知、异常通知、环绕通知(!joinPoint.proceed())2.3切面类中@Aspect必须写

疫情足迹举例:

使用自我扫码进入形式和神奇设备负责记录形式两种形式,如图所示:

自我扫码进入形式

代码部分:

Person.java

/*** Person类,用于演示疫情足迹登录* @author Katrina**/
public class Person {/*** 回家*/public void goHome() {System.out.println("回家扫码登记...");System.out.println("回家了");System.out.println("离家扫码登记...");}/*** 去商场购物生活必需品*/public void goMarket() {System.out.println("去商场扫码登记...");System.out.println("去商场购买生活必需品");System.out.println("离开商场扫码登记...");}/*** 去工作*/public void goWork() {System.out.println("去工作扫码登记...");System.out.println("去工作");System.out.println("离开扫码登记...");}}

PersonTest.java

/*** 测试类,用于演示疫情足迹记录* @author Katrina**/
import org.junit.Test;
public class PersonTest {/*** 测试非AOP疫情登记*/@Testpublic void test1() {Person person = new Person();person.goHome();person.goWork();person.goMarket();}}
效果图:

神奇设备负责记录形式【xml形式配置AOP】

引入aspectjweaver-1.9.5.jarjar包

代码部分:

part1:

AOPPerson.java
/*** AOPPerson类,用于演示AOP* @author Katrina**/
public class AOPPerson {/*** 回家方法*/public void goHome() {System.out.println("回家了");}/*** 去商场方法*/public void goMarket(String markerName) {System.out.println("去商场");}/*** 去工作方法*/public void goWork() {System.out.println("去工作");}}
SuperMachine.java
/*** 超级机器,用于定义通知* @author Katrina**/
public class SuperMachine {/*** 进入前(方法执行前)进行登记信息*/public void beforeIn() {System.out.println("进入前登记信息...");}/*** 离开前(方法执行之后)进行登记信息*/public void beforeOut() {System.out.println("离开之前登记信息...");}}
config.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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!-- 注入类 --><bean id="AOPPerson" class="demo.AOPPerson"></bean><bean id="superMachine" class="demo.SuperMachine"></bean><!-- AOP配置 --><aop:config><!-- 切面配置 --><aop:aspect ref="superMachine"><!-- 定义切点:1.execution(执行): 2.表达式:execution(public * demo.AOPPerson.goHome(..) -> public void goHome() {表达式就是方法的描述:【访问修饰符 返回值 方法的全路径(参数列表)】通配符:*(全部)、..(0个或者多个)--><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.goHome())" id="pointCut"/> --><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.*())" id="pointCut"/> --><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.*(..))" id="pointCut"/> --><aop:pointcut expression="execution(public * demo.AOPPerson.*(..))" id="pointCut"/><!-- 注意:必须需要ref关联 --><!-- 前置通知:执行方法之前执行 --><aop:before method="beforeIn" pointcut-ref="pointCut"/><!-- 后置通知:执行方法之后执行 --><aop:after method="beforeOut" pointcut-ref="pointCut"/></aop:aspect></aop:config>
</beans>
AOPPersonTest.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*** aop方式测试类* @author Katrina**/
public class AOPPersonTest {private ClassPathXmlApplicationContext context;@Beforepublic void before() {context = new ClassPathXmlApplicationContext("config.xml");}/*** aop的demo*/@Testpublic void test1() {AOPPerson person = context.getBean(AOPPerson.class);person.goHome();person.goMarket("万达超市");person.goWork();}@Afterpublic void after() {context.close();}}
效果图:

part2:

SuperMachine.java
/*** 超级机器,用于定义通知* @author Katrina**/
public class SuperMachine {/*** 进入前(方法执行前)进行登记信息*/public void beforeIn() {System.out.println("进入前登记信息...");}/*** 离开前(方法执行之后)进行登记信息*/public void beforeOut() {System.out.println("离开之前登记信息...");}/*** 返回通知*/public void returnMethod() {System.out.println("返回通知执行了...");}}
config.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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!-- 注入类 --><bean id="AOPPerson" class="demo.AOPPerson"></bean><bean id="superMachine" class="demo.SuperMachine"></bean><!-- AOP配置 --><aop:config><!-- 切面配置 --><aop:aspect ref="superMachine"><!-- 定义切点:1.execution(执行): 2.表达式:execution(public * demo.AOPPerson.goHome(..) -> public void goHome() {表达式就是方法的描述:【访问修饰符 返回值 方法的全路径(参数列表)】通配符:*(全部)、..(0个或者多个)--><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.goHome())" id="pointCut"/> --><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.*())" id="pointCut"/> --><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.*(..))" id="pointCut"/> --><aop:pointcut expression="execution(public * demo.AOPPerson.*(..))" id="pointCut"/><!-- 注意:必须需要ref关联 --><!-- 前置通知:执行方法之前执行 --><aop:before method="beforeIn" pointcut-ref="pointCut"/><!-- 后置通知:执行方法之后执行 --><aop:after method="beforeOut" pointcut-ref="pointCut"/><!-- 返回通知:方法成功执行之后执行 --><aop:after-returning method="returnMethod" pointcut-ref="pointCut"/></aop:aspect>   </aop:config>
</beans>
效果图:

不对test进行修改,效果如图所示:

其他情况,若修改回家方法(添加参数),且在赋值的时候有误,则效果如图所示:


part3:

SuperMachine.java
/*** 超级机器,用于定义通知* @author Katrina**/
public class SuperMachine {/*** 进入前(方法执行前)进行登记信息*/public void beforeIn() {System.out.println("进入前登记信息...");}/*** 离开前(方法执行之后)进行登记信息*/public void beforeOut() {System.out.println("离开之前登记信息...");}/*** 返回通知*/public void returnMethod() {System.out.println("返回通知执行了...");}/*** 异常通知*/public void afterThrowing() {System.out.println("出现异常了...");}}
config.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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!-- 注入类 --><bean id="AOPPerson" class="demo.AOPPerson"></bean><bean id="superMachine" class="demo.SuperMachine"></bean><!-- AOP配置 --><aop:config><!-- 切面配置 --><aop:aspect ref="superMachine"><!-- 定义切点:1.execution(执行): 2.表达式:execution(public * demo.AOPPerson.goHome(..) -> public void goHome() {表达式就是方法的描述:【访问修饰符 返回值 方法的全路径(参数列表)】通配符:*(全部)、..(0个或者多个)--><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.goHome())" id="pointCut"/> --><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.*())" id="pointCut"/> --><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.*(..))" id="pointCut"/> --><aop:pointcut expression="execution(public * demo.AOPPerson.*(..))" id="pointCut"/><!-- 注意:必须需要ref关联 --><!-- 前置通知:执行方法之前执行 --><aop:before method="beforeIn" pointcut-ref="pointCut"/><!-- 后置通知:执行方法之后执行 --><aop:after method="beforeOut" pointcut-ref="pointCut"/><!-- 返回通知:方法成功执行之后执行 --><aop:after-returning method="returnMethod" pointcut-ref="pointCut"/><!-- 异常通知:方法出现异常后执行 --><aop:after-throwing method="afterThrowing" pointcut-ref="pointCut"/></aop:aspect></aop:config>
</beans>
效果图:

情况一,在测试类中修改代码为:person.goHome("123abc");,效果如图所示:

情况二,在测试类中修改代码为:person.goHome("123");,效果如图所示:

part4:

SuperMachine.java
import org.aspectj.lang.ProceedingJoinPoint;
/*** 超级机器,用于定义通知* @author Katrina**/
public class SuperMachine {/*** 环绕通知* @param joinPoint,一定要调用proceed方法*/public void around(ProceedingJoinPoint joinPoint) {System.out.println("进入前进行登记信息");boolean hasError = false;try {joinPoint.proceed(); //执行业务方法 } catch (Throwable e) {e.printStackTrace();System.out.println("出现异常了...");hasError = true;} if (hasError) {System.out.println("出现异常信息");} else {System.out.println("成功返回值信息");}System.out.println("离开前进行登记信息");}/*** 进入前(方法执行前)进行登记信息*/public void beforeIn() {System.out.println("进入前登记信息...");}/*** 离开前(方法执行之后)进行登记信息*/public void beforeOut() {System.out.println("离开之前登记信息...");}/*** 返回通知*/public void returnMethod() {System.out.println("返回通知执行了...");}/*** 异常通知*/public void afterThrowing() {System.out.println("出现异常了...");}}
config.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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!-- 注入类 --><bean id="AOPPerson" class="demo.AOPPerson"></bean><bean id="superMachine" class="demo.SuperMachine"></bean><!-- AOP配置 --><aop:config><!-- 切面配置 --><aop:aspect ref="superMachine"><!-- 定义切点:1.execution(执行): 2.表达式:execution(public * demo.AOPPerson.goHome(..) -> public void goHome() {表达式就是方法的描述:【访问修饰符 返回值 方法的全路径(参数列表)】通配符:*(全部)、..(0个或者多个)--><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.goHome())" id="pointCut"/> --><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.*())" id="pointCut"/> --><!-- <aop:pointcut expression="execution(public void demo.AOPPerson.*(..))" id="pointCut"/> --><aop:pointcut expression="execution(public * demo.AOPPerson.*(..))" id="pointCut"/><!-- 注意:必须需要ref关联 --><!-- 前置通知:执行方法之前执行 --><!-- <aop:before method="beforeIn" pointcut-ref="pointCut"/> --><!-- 后置通知:执行方法之后执行 --><!-- <aop:after method="beforeOut" pointcut-ref="pointCut"/> --><!-- 返回通知:方法成功执行之后执行 --><!-- <aop:after-returning method="returnMethod" pointcut-ref="pointCut"/> --><!-- 异常通知:方法出现异常后执行 --><!-- <aop:after-throwing method="afterThrowing" pointcut-ref="pointCut"/> --><!-- 环绕通知 --><aop:around method="around" pointcut-ref="pointCut"/></aop:aspect></aop:config>
</beans>
效果图:

情况一,在测试类中修改代码为:person.goHome("123");,效果如图所示:

情况二,在测试类中修改代码为:person.goHome("abc");,效果如图所示:

注解形式配置AOP

代码部分:

part1:

UserControllor.java

import org.springframework.stereotype.Controller;
/*** UserControllor,用于演示注解形式的切面编程* @author Katrina**/
@Controller
public class UserControllor {/*** 添加用户操作*/public void addUser() {System.out.println("添加用户成功...");}/*** 编辑用户操作*/public void editUser() {System.out.println("编辑用户成功...");}}

LogAOP.java

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/*** 日志的切面* @author Katrina**/
@Component
@Aspect //标明LogAOP是切面类
public class LogAOP {/** 1.声明切点* 2.声明通知*/@Pointcut(value = "execution(public * anno.UserControllor.*(..))")public void pointCut() { }/*** 使用@Before声明前置通知*/@Before(value = "pointCut()")public void log() {System.out.println("在此处记录日志...");}/*** 使用@After声明后置通知*/@After(value = "pointCut()")public void after() {System.out.println("后置通知执行了...");}}

anno-config.java

<?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!-- 开启包扫描 --><context:component-scan base-package="anno"></context:component-scan><!-- 开启AOP --><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

UserControllorTest.java

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*** 用于演示注解形式使用AOP* @author Katrina**/
public class UserControllorTest {@Testpublic void test() {//1.获取容器ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("anno-config.xml");//2.取出实例,做操作UserControllor userControllor = context.getBean(UserControllor.class);userControllor.addUser();//3.关闭容器context.close();}}
效果图:

part2:

UserControllor.java

import org.springframework.stereotype.Controller;
/*** UserControllor,用于演示注解形式的切面编程* @author Katrina**/
@Controller
public class UserControllor {/*** 添加用户操作*/public void addUser(String number) {System.out.println("添加用户成功...");Integer.parseInt(number); //解析,可制造错误(如:1/0)}/*** 编辑用户操作*/public void editUser() {System.out.println("编辑用户成功...");}}

LogAOP.java

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/*** 日志的切面* @author Katrina**/
@Component
@Aspect //标明LogAOP是切面类
public class LogAOP {/** 1.声明切点* 2.声明通知*/@Pointcut(value = "execution(public * anno.UserControllor.*(..))")public void pointCut() { }/*** 使用@Before声明前置通知*/@Before(value = "pointCut()")public void log() {System.out.println("在此处记录日志...");}/*** 使用@After声明后置通知*/@After(value = "pointCut()")public void after() {System.out.println("后置通知执行了...");}/*** 使用@AfterReturning声明返回通知*/@AfterReturning(value = "pointCut()")public void afterReturning() {System.out.println("方法成功执行了...");}}
效果图:

情况一,在测试类中修改代码为:person.goHome("111");,效果如图所示:

情况二,在测试类中修改代码为:person.goHome("abc");,效果如图所示:

part3:

LogAOP.java

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/*** 日志的切面* @author Katrina**/
@Component
@Aspect //标明LogAOP是切面类
public class LogAOP {/** 1.声明切点* 2.声明通知*/@Pointcut(value = "execution(public * anno.UserControllor.*(..))")public void pointCut() { }/*** 使用@Before声明前置通知*/@Before(value = "pointCut()")public void log() {System.out.println("在此处记录日志...");}/*** 使用@After声明后置通知*/@After(value = "pointCut()")public void after() {System.out.println("后置通知执行了...");}/*** 使用@AfterReturning声明返回通知*/@AfterReturning(value = "pointCut()")public void afterReturning() {System.out.println("方法成功执行了...");}/*** 使用@AfterThrowing表明异常通知*/@AfterThrowing(value = "pointCut()")public void afterThrowing() {System.out.println("发生异常了...");}}
效果图:

情况一,在测试类中修改代码为:person.goHome("abc");,效果如图所示:

情况二,在测试类中修改代码为:person.goHome("111");,效果如图所示:

part4:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/*** 日志的切面* @author Katrina**/
@Component
@Aspect //标明LogAOP是切面类
public class LogAOP {/** 1.声明切点* 2.声明通知*/@Pointcut(value = "execution(public * anno.UserControllor.*(..))")public void pointCut() { }/*** 使用@Before声明前置通知*/
//  @Before(value = "pointCut()")public void log() {System.out.println("在此处记录日志...");}/*** 使用@After声明后置通知*/
//  @After(value = "pointCut()")public void after() {System.out.println("后置通知执行了...");}/*** 使用@AfterReturning声明返回通知*/
//  @AfterReturning(value = "pointCut()")public void afterReturning() {System.out.println("方法成功执行了...");}/*** 使用@AfterThrowing表明异常通知*/
//  @AfterThrowing(value = "pointCut()")public void afterThrowing() {System.out.println("发生异常了...");}/*** 使用@Around注解声明环绕通知* @param joinPoint*/@Around(value = "pointCut()")public void around(ProceedingJoinPoint joinPoint) {System.out.println("执行方法之前");try {joinPoint.proceed(); //执行业务方法} catch (Throwable e) {e.printStackTrace();System.out.println("出现异常了...");}System.out.println("执行方法之后");}}
效果图:

情况一,在测试类中修改代码为:person.goHome("111");,效果如图所示:

情况二,在测试类中修改代码为:person.goHome("abc");,效果如图所示:

Spring实战学习笔记整理(4)-AOP(面向切面编程)相关推荐

  1. Spring学习之旅(二) AOP(面向切面编程)的使用

    辛苦堆砌,转载请注明出处,谢谢! 上一篇说了Spring的依赖注入,今天再看看Spring的AOP,牵扯的AOP的理论知识,大家可以搜索一些文章了解一下,这里不做过多解释,本文主要介绍使用Spring ...

  2. python aop编程_学习笔记: AOP面向切面编程和C#多种实现

    AOP:面向切面编程   编程思想 OOP:一切皆对象,对象交互组成功能,功能叠加组成模块,模块叠加组成系统 类--砖头     系统--房子 类--细胞     系统--人 面向对象是非常适合做大型 ...

  3. 大数据WEB阶段Spring框架 AOP面向切面编程(一)

    Spring - AOP面向切面编程(一) 一.代理模式概述 代理的特点:(目标对象即被代理者) 实现和目标对象相同的接口 具备和目标对象的方法 代理者不仅要做目标对象的方法 , 还要做一些额外的操作 ...

  4. 大数据WEB阶段Spring框架 AOP面向切面编程(二)

    Spring AOP面向切面编程(二) 一.切入点的execution表达式 execution的表达形式: execution(修饰符? 返回值类型 所在包类? 方法名(参数列表) 异常?) ?表示 ...

  5. spring中AOP(面向切面编程)

    spring中AOP(面向切面编程) 面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是spring框架中的一个重要内容 ...

  6. Spring AOP面向切面编程

    AOP面向切面编程: AOP(Aspect Oriented Programming),即面向切面编程,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公 ...

  7. 【SSM】Spring系列——AOP面向切面编程

    文章目录 03 AOP面向切面编程 3.1 AOP概述 3.2 面向切面编程对有什么好处 3.3 模拟AOP框架实现 3.3.1 代码实现版本一 3.3.2 代码实现版本二 3.3.3 代码实现版本三 ...

  8. Java绝地求生—Spring AOP面向切面编程

    Java绝地求生-Spring AOP面向切面编程 背景 动态代理 构建被代理对象 自动生成代理 调用动态代理 Spring方法 方式一:使用Spring的API接口 方式二:使用自定义类 方式三:使 ...

  9. java aop面向切面编程

    最近一直在学java的spring boot,一直没有弄明白aop面向切面编程是什么意思.看到一篇文章写得很清楚,终于弄明白了,原来跟python的装饰器一样的效果.http://www.cnblog ...

  10. AOP面向切面编程之全局日志打印/统计接口耗时

    目录 一.什么是AOP 二.AOP使用场景 三.使用AOP的好处 四.先举个例子理解AOP面向切面编程 五.Spring5.X的AOP切入点表达式有这些种写法 六.实战基于Spring的AOP快速实现 ...

最新文章

  1. 以太坊C++客户端Aleth源码分析,转账交易和智能合约的入口代码
  2. 42.虚拟内存如何设置:
  3. python入门作业编程题-【python基础语法】第10天作业练习题
  4. Spark Java API:broadcast、accumulator
  5. 'mysql_attr_use_buffered_query'_php中mysql操作的buffer知识
  6. 整理90部好看的经典喜剧片
  7. mac中rabbitmq的安装
  8. LinkedList 真的是查找慢增删快?刷新你的认知!
  9. mac定时备份mysql_定时备份mysql数据库
  10. 关于html中的reset,submit中的按钮不能实现功能的原因
  11. 微信H5禁止分享功能
  12. 计算机无法进去系统,电脑开机后进不了系统的解决方法步骤图
  13. linux系统下如何解压RAR文件软件rarforlinux
  14. 从315晚会曝光网秦谈企业社会责任
  15. MySQL——in和exists优化
  16. 淘宝按关键词搜索天猫商品接口调用展示
  17. localStorage使用实例-进入显示广告,点击关闭之后,刷新网页不再出现
  18. 认识服务器的几大必备知识
  19. 猴子选大王(c语言)
  20. 进程间各种通信方式的C++实现

热门文章

  1. pdf打开错误之读取本文档时出现问题(14)
  2. 2018——走过的路
  3. opencv+paddle orc 识别图片提取表格信息
  4. 基于JSP的鲜花店商城平台【数据库设计、源码、开题报告】
  5. Python学习——Caesar Cipher密码破解(加密)方法
  6. A股将迎来一大波新经济公司:几家欢喜几家愁
  7. 温度对免疫代谢调节和癌症进展的影响
  8. Win10下WinRAR“拒绝访问”解决+获取everyone权限
  9. Kaminari分页
  10. thinkphp的column()函数