1、什么是AOP

AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 面向方面的编程(AOP)是一种新的编程技术,它弥补了面向对象的编程(OOP)在跨越模块行为上的不足。AOP 引进了 Aspect,它将影响多个类的行为封装到一个可重用模块中,它允许程序员对横切关注点进行模块化,从而消除了 OOP 引起的代码混乱和分散问题,增强了系统的可维护性和代码的重用性

2、AOP在Spring中的作用

  • 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 …

  • 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。

  • 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。

  • 目标(Target):被通知对象。

  • 代理(Proxy):向目标对象应用通知之后创建的对象。

  • 切入点(PointCut):切面通知 执行的 “地点”的定义。

  • 连接点(JointPoint):与切入点匹配的执行点。

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

即 Aop 在 不改变原有代码的情况下 , 去增加新的功能 .

3、使用Spring实现Aop

准备工作:需要导入一个依赖包:

        <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version></dependency>

第一种实现方式:

通过Spring API实现,编写业务接口和实现类

public interface UserService {/*** 增加*/void add();
}
public class UserServiceImpl implements UserService {@Overridepublic void add() {System.out.println("执行了add方法");}
}

编写增强类,一个前置,一个后置

public class Log implements MethodBeforeAdvice {/*** target:目标对象* args:参数* method:目标对象的方法*/@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(target.getClass().getName()+"执行了"+method.getName()+"方法");}
}
public class AfterLog implements AfterReturningAdvice {/*** returnValue:返回值*/@Overridepublic void afterReturning(Object returnValue, Method method, Object[] objects, Object o1) throws Throwable {System.out.println("执行了"+method.getName()+"方法,返回结果"+returnValue);}
}

编写配置文件,注意导入aop约束

<?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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="com.lili.service.UserServiceImpl"/><bean id="log" class="com.lili.log.Log"/><bean id="afterLog" class="com.lili.log.AfterLog"/><!--方式一:使用原生Spring API接口 --><!--配置aop:需要导入aop的约束--><aop:config><!--切入点:expression:表达式,execution(要执行的位置! * * * * *) --><aop:pointcut id="pointcut" expression="execution(* com.lili.service.UserServiceImpl.*(..))"/><!--执行环绕增加!--><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config>
</beans>

测试:

    @Testpublic void test1(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = context.getBean("userService", UserService.class);userService.add();}

输出:

com.lili.service.UserServiceImpl执行了add方法
执行了add方法
执行了add方法,返回结果null

第二种方式:

自定义类来实现AOP

编写植入类

public class OneSelfPointcut {public void before() {System.out.println("使用前");}public void after() {System.out.println("使用后");}
}

编写配置:

<beans>
<!--方式二:自定义类--><bean id="oneSelfPointcut" class="com.lili.onself.OneSelfPointcut"/><aop:config><!--自定义切面, ref 要引用的类--><aop:aspect ref="oneSelfPointcut"><!--切入点--><aop:pointcut id="point" expression="execution(* com.lili.service.UserServiceImpl.*(..))"/><!--通知--><aop:before method="before" pointcut-ref="point"/><aop:after method="after" pointcut-ref="point"/></aop:aspect></aop:config>
</beans>

运行:

使用前
执行了add方法
使用后

第三种方式:

使用注解来实现AOP

编写使用注解实现的类

@Aspect// 标注此类是一个切面
public class AnnotationPointCut {@Before("execution(* com.lili.service.UserServiceImpl.*(..))")public void before(){System.out.println("方法执行前");}@After("execution(* com.lili.service.UserServiceImpl.*(..))")public void after(){System.out.println("方法执行后");}
}

编写配置:

    <!--方式三--><bean id="annotationPointCut" class="com.lili.onself.AnnotationPointCut"/><!--开启注解支持!   JDK(默认 proxy-target-class="false")   cglib(proxy-target-class="true")--><aop:aspectj-autoproxy/>

运行:

方法执行前
执行了add方法
方法执行后

Spring中实现AOP的三种方式相关推荐

  1. Spring实战(三)Spring中装配Bean的三种方式---XML、JavaConfig、AutoWire

    创建应用对象之间协作关系的行为称为装配(wiring),这也是依赖注入的本质. Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,而开发者需要告诉Spring需要创建哪些 ...

  2. Spring中bean实例化的三种方式:默认构造、静态工厂、实例工厂

    1. 默认构造方式:必须提供默认构造 <bean id="bean id" class="工厂全限定类名"></bean> 以Studn ...

  3. Spring中的AOP(三)——基于Annotation的配置方式(一)

    为什么80%的码农都做不了架构师?>>>    AspectJ允许使用注解用于定义切面.切入点和增强处理,而Spring框架则可以识别并根据这些注解来生成AOP代理.Spring只是 ...

  4. java中四种注入注解,Spring中依赖注入的四种方式

    在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的sett ...

  5. Django中Model继承的三种方式

    Django中Model继承的三种方式 Django中Model的继承有三种: 1.抽象继承 2.多表继承 3.proxy model(代理model) 1.抽象继承 第一种抽象继承,创建一个通用父类 ...

  6. android获取自定义属性,android 自定义控件中获取属性的三种方式(转)

    第一种方法,直接设置属性值,通过attrs.getAttributeResourceValue拿到这个属性值. (1)在xml文件中设置属性值 android:layout_width="f ...

  7. UE4学习-在虚幻编辑器中打开VS的三种方式

    文章目录 方式一 方式二 方式三 在虚幻编辑器中打开VS的三种方式 方式一 在文件浏览器这里,选择C++类,然后在文件夹内,找到一个和截图中类似的图标,双击,即打开vs,并在vs中打开这个类的代码. ...

  8. Java中实现接口的三种方式您造吗?

    本文介绍了Java中实现接口的三种方式:常规实现方式.匿名内部类和 Lambda表达式实现方式.希望已经了解的同学可以重新温习一下,不了解的同学则从中受益! Java中接口最常规的实现方式 同学们都会 ...

  9. java中实现多线程的三种方式

    java中实现多线程的三种方式 1.实现多线程的方法: 在java中实现多线程的两途径:继承Thread类,实现Runable接口(Callable) 2.继承Thread类实现多线程: ​ 继承类T ...

  10. java类初始数组_java中数组初始化的三种方式是什么

    java中数组初始化的三种方式是:1.静态初始化,如[int a[] = {2, 0, 1, 9, 2020}]:2.动态初始化,如[int[] c = new int[4]]:3.默认初始化,如[i ...

最新文章

  1. mysql 数据操作 单表查询 where约束 between and or
  2. Starting MySQL....The server quit without updating PID file 处理方法
  3. 最详细的maven教程,可以收藏!
  4. short,int,long ,long long ,_int64类型的范围详解
  5. 获取自定义data的几种属性
  6. devops流程工具_您的DevOps工作流程依赖哪些工具?
  7. JDWP Transport dt socket failed to initialize
  8. 杯水车薪!昔日手机巨头今拍卖外观设计专利抵债 起拍价仅2.11万元
  9. java判断线段是否相交函数_计算几何-判断线段是否相交
  10. 【算法笔记】:区间覆盖问题:贪心算法
  11. VALSE学习(一):high-resolution representation learning-高分辨率表示学习-姿态估计
  12. 这就是Machine Learning
  13. bzoj2655 calc
  14. 图解sql内外连接和左连接left join和右连接right join
  15. 将DataFrame表格以图片形式输出
  16. 论文阅读《LSD-SLAM: Large-Scale Direct Monocular SLAM》
  17. Apache服务器的下载、安装、配置等等
  18. Icon和Ico图片的区别
  19. excel组合汇总_Excel汇总20150302
  20. 手把手教你写一个脚手架

热门文章

  1. javaMail简介(一)
  2. MooTools 1.4 源码分析 - Fx
  3. 动态载入.ascx用户控件
  4. android sid如何验证有效性,使用RMAN验证备份的有效性
  5. java基础中如何中断/阻塞线程和使用中断
  6. 使用OQL语言查询对象信息
  7. 分布式事务解决方案总结
  8. JavaScript的==和Java的==比较
  9. SpringBoot中配置多环境的配置文件
  10. linux系统修改时区的方法