一、AOP


1 Spring AOP 的实现原理

  • 是对OOP编程方式的一种补充。翻译过来为“面向切面编程”。

  • 1 AspectJ是静态代理的增强:所谓静态代理就是AOP框架会在便一阶段生成AOP代理类,也叫编译器增强。

  • 2 使用Spring AOP

    • 与AspectJ 的静态代理不同,Spring AOP使用的是动态代理,动态代理指AOP框架不会去修改字节码,而是在内存中临时生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并在特定的切点做了增强处理,并回调原对象的方法。
    • Spring AOP中的动态代理有两种:JDK动态代理(代理必须实现一个接口)、CGLIB动态代理(代理可以不实现接口)
    • 几个概念:
      • 切面(Advisor):是AOP中的一个术语,表示从业务逻辑中分离出来的横切逻辑比如性能监控、日志处理、权限控制等
        这些功能都可以从核心的业务逻辑中抽离出去。可以解决代码耦合的问题,职责更加单一。封装了增强和切点。
      • 增强(Advice):增强代码的功能的类,横切到代码中。
      • 目标:目标方法(JDK代理)或目标类(CGLIB代理)。
      • 代理:通过ProxyFactory类生成,分为JDK代理、CGLIB代理。
      • 切点:通过一个条件来匹配拦截的类,这个条件成为切点。
      • 连接点:作为增强方法的入参,可以获取目标方法的信息。
    • 增强
      • 织入(Weaving):将切面应用到目标对象并导致代理对象创建的过程。

        • 1 前置增强(Before):在目标方法前调用。
        • 2 后置增强(AfterAdvice):在目标方法后调用。
        • 3 环绕增强(AroundAdvice):将Before和After,甚至抛出增强和返回增强合到一起。
        • 4 返回增强(AfterReturningAdvice):在方法返回结果后执行,该增强可以接收到目标方法返回的结果。
        • 5 抛出增强(AfterThrowingAdvice):在目标方法抛出对应的类型后执行,可以接收到对应的异常信息。
      • 引入增强(DeclareParentsAdvice):想让程序在运行的时候动态实现某个接口,需要引入增强。
  • 3 注解:Spring + AspectJ

    • 1 对切面类添加 @Aspect 注解将切面类和目标类放入到IOC容器中,可以通过<context:component-scan base-package=""/>进行扫描。
    • 2 添加增强方法(包括增强类型和切点表达式,以及连接点)。
    • 3 在Spring 配置文件中添加<aop:aspectj-autoproxy proxy-target-class="true"/> ,false表示只能代理接口(JDK动态代理),true表示代理类(CGLIB代理)。
    • 3.1 通过切点表达式(AspectJ execution)进行拦截

      • 步骤一:配置pox.xml:
<!--Spring AOP依赖-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version>
</dependency>
  • 步骤二:spring-config.xml
<!-- 注解扫描-->
<context:component-scan base-package="com.sean.aoptest"></context:component-scan>
<!-- 设置aop动态代理类型:true为代理类,false为代理接口 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
  • 步骤三:编写代码,在这里我上传一段测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-config-test.xml"})
public class SpringTest{@Autowiredprivate Student student;@Testpublic void test01(){System.out.println(student.say("zengxing"));}
}@Component
class Student implements Person{@Overridepublic String say(String name) {// TODO Auto-generated method stub
//      if (name.equals("zengxing")) {
//          throw new RuntimeException("名字不能是" + name);      //要抛出运行时异常
//      }return "Hello, " + name;}}///*
around before...
before
around after...
after
str:Hello, zengxing
afterReturningAdvice
Hello, zengxing
*///@Aspect
@Component
class LoggingAspect{//前置@Before("execution(String say(String))")public void before(JoinPoint point){System.out.println("before");}//后置@After("execution(String say(String))")public void after(JoinPoint point){System.out.println("after");}//环绕@Around("execution(String say(String))")public Object around(ProceedingJoinPoint point) throws Throwable{System.out.println("around before...");Object result = point.proceed();System.out.println("around after...");return result;}//返回@AfterReturning(value="execution(String say(String))", returning="str")public void afterReturningAdvice(JoinPoint point, String str){System.out.println("str:" + str);System.out.println("afterReturningAdvice");}//抛出@AfterThrowing(value = "execution(String say(String))", throwing = "e")public void afterThrowingAdvice(JoinPoint point, Exception e){String message = e.getMessage();System.out.println(message);System.out.println("AfterThrowingAdvice...");}
}
  • 3.2 通过切点注解表达式(AspectJ @annotation)进行拦截

    • 开发步骤:

      • 1 定义注解类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface AuthorityTag { }
  • 2 为切面类中增强指定注解表达式
@Aspect
@Component
class AuthorityAspect{@Before("@annotation(com.sean.aoptest.AuthorityTag)")public void before(JoinPoint point){System.out.println("authority before");}
}
  • 3 在目标类目标方法上标注注解
@Component      //将对象放入到IOC容器中
class Car1 implements Wheel{@AuthorityTag  //标注切入的的增强@Overridepublic void run(){System.out.println("I am a car, i can run");}
}
  • 4 小的知识点

    • 利用方法签名编写 AspectJ 切点表达式

      • execution * com.sean.Calculator.* (…):匹配Calculator中声明的所有方法,
        第一个 * 代表任意修饰符及任意返回值。第二个 * 代表任意方法。…匹配任意数量的参数。若目标类与接口与该切面在同一个包中,可以省略包名。
      • execution public * Calculator.*(…):匹配ArithmeticCalculator 接口的所有公有方法。
      • execution public double Calculator.*(…):匹配Calculator中返回double类型数值的方法。
      • execution public double Calculator.*(double, …):匹配第一个参数为double类型的方法,…匹配任意数量任意类型的参数。
      • execution public double Calculator.*(double, double):匹配参数类型为double,double类型的方法。
    • 可以结合切点表达式使用 &&, ||, ! 来合并。如:
      • execution(void run()) || execution(void say())
    • 切面优先级:
      • 可以通过实现Ordered接口或利用@Order注解指定。
      • 1 实现Ordered接口,getOrder()方法返回的值越小,优先级越高。
      • 2 使用@Order注解,需要出现在注解中,同样是值越小优先级越高。

参考博客:https://blog.csdn.net/qq_16605855/article/details/73465865

重新学习Spring2——IOC和AOP原理彻底搞懂相关推荐

  1. 【Spring 源码阅读】Spring IoC、AOP 原理小总结

    Spring IoC.AOP 原理小总结 前言 版本约定 正文 Spring BeanFactory 容器初始化过程 IoC 的过程 bean 完整的创建流程如下 AOP 的过程 Annotation ...

  2. Spring总结(IOC、AOP原理以及Spring事务)

    一.概述 1.Spring是一个开源免费且轻量级的框架 , 非侵入式的 . 2.控制反转 IoC , 面向切面 Aop 3 .对事物的支持 , 对框架的支持 一句话概括: Spring 是一个轻量级的 ...

  3. 初学者快速了解spring的IOC和AOP原理

    spring框架概述 1.spring是轻量级的开源的javaEE框架 2.spring可以解决企业应用开发的复杂性 3.spring有两个核心部分:IOC和AOP (1)IOC:控制反转,把创建对象 ...

  4. springaop事务逻辑原理_搞懂Spring AOP,这一篇就够了

    看了这篇文章,如果你还是不会用AOP来写程序,请你打我!! =.=||| 引言 Spring AOP是一个对AOP原理的一种实现方式,另外还有其他的AOP实现如AspectJ等. AOP意为面向切面编 ...

  5. php service原理,轻松搞懂WebService工作原理

    用更简单的方式给大家谈谈WebService,让你更快更容易理解,希望对初学者有所帮助. WebService是基于网络的.分布式的模块化组件. 我们直接来看WebService的一个简易工作流程: ...

  6. Java轻量级业务层框架Spring两大核心IOC和AOP原理

    IoC(Inversion of Control): IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些 ...

  7. [Spring入门学习笔记][Spring的AOP原理]

    AOP是什么? 面向切面编程 软件工程有一个基本原则叫做"关注点分离"(Concern Separation),通俗的理解就是不同的问题交给不同的部分去解决,每部分专注于解决自己的 ...

  8. 从原理上搞懂如何设置线程池参数大小?

    我们在使用线程池的时候,会有两个疑问点: 线程池的线程数量设置过多会导致线程竞争激烈 如果线程数量设置过少的话,还会导致系统无法充分利用计算机资源 那么如何设置才不会影响系统性能呢? 其实线程池的设置 ...

  9. ES6学习笔记(一):轻松搞懂面向对象编程、类和对象

    文章目录 面向过程编程P OP(Process oriented programming) 面向对象编程OOP(Object Oriented Programming) ES6中的类和对象 面向对象 ...

最新文章

  1. 【笔记】微软OneNote使用笔记,OneNote备份问题
  2. redis的安全性及客户端工具的使用
  3. 对android.mk debug
  4. charles 代理手机连不上网_Charles设置代理后,手机无法上网
  5. ios把数据传递到另一个页面_iOS 委托 页面之间传递数值
  6. 揭秘!信息检索技术高端玩法
  7. 寄存器(内存访问)07 - 零基础入门学习汇编语言19
  8. 【4】求最大奇数公约数
  9. 基于DenseNet的图像识别
  10. 51单片机 日历 c语言 数码管,51单片机做的数码管电子日历
  11. 2015-5-10分享的PDF
  12. Wker_SQLTool注入工具(附源码)
  13. 【Android】achartengine的柱状图和饼状图的使用
  14. 盒式交换机S5750系列指示灯含义
  15. 计算机毕业设计Java“小蜜蜂”校园代取快递系统(源码+系统+mysql数据库+lw文档)
  16. word文档使用技巧
  17. ADC—应用交付-AX系列
  18. DRM系列(7)之drmModeAtomicCommit底层流程
  19. 关于“要不要做调研”
  20. MatLab SimuLink国产代替

热门文章

  1. [HDU 6157]The Karting(DP)
  2. YBTOJ危桥通行洛谷P3163:危桥通行(网络流)
  3. P6672-[清华集训2016]你的生命已如风中残烛【结论】
  4. nssl1469-W【dp】
  5. 2021牛客暑期多校训练营7 K-xay loves sequence(主席树+二分)
  6. Codeforces Round #667 (Div. 3)
  7. springboot 多数据源mybatis的两种整合方法
  8. 我终于搞清楚了和String有关的那点事儿
  9. 如何在一分钟内搞定面试官
  10. MySQL sysdate()函数