spring ioc 和 aop

    记录面试中问到的spring ioc 和 aop的概念和原理。

    Spring 底层 IoC 容器的设计实现也是非常完美的,在整个 Spring 应用上下文的生命周期和 Spring Bean 的生命周期的许多阶段提供了相应的扩展点,供开发者自行扩展,使得框架非常的灵活。

Spring拥有两大特性:IoC和AOP。IoC,英文全称Inversion of Control,意为控制反转。AOP,英文全称Aspect-Oriented Programming,意为面向切面编程。

Spring核心容器的主要组件是Bean工厂(BeanFactory),Bean工厂使用控制反转(IoC)模式来降低程序代码之间的耦合度,并提供了面向切面编程(AOP)的实现。

简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面编程(AOP)的容器框架。

 控制反转(IoC)

控制反转,简单点说,就是创建对象的控制权,被反转到了Spring框架上。

通常,我们实例化一个对象时,都是使用类的构造方法来new一个对象,这个过程是由我们自己来控制的,而控制反转就把new对象的工交给了Spring容器。

IoC的主要实现方式有两种:依赖查找、依赖注入。

依赖注入是一种更可取的方式。

先来说说传统使用java实例的不足,一般有两种方式:

通过new关键字实例化一个对象;

通过工厂模式生产一个实例对象;

第一种方式必然导致调用者和被依赖对象存在硬编码耦合,非常不利于项目升级的维护;第二种比第一种好很多,但是调用组件需要主动通过工厂去获取被依赖的对象,这就会带来调用组件与被依赖工厂的耦合。

那么IOC有什么好处呢?

调用者无需主动获取被依赖的对象,只要被动接受Spring容器为调用者的成员变量即可。总体来说就是主动变为被动,所以被称为控制反转。

场景

依赖注入一般有以下两种:

设值注入:IoC容器使用成员变量的setter方法来注入被依赖对象;

构造注入:IoC容器通过构造器来注入被依赖对象;

建议采用设值注入为主,构造注入为辅的注入策略。对于依赖关系无需变化的注入,尽量采用构造注入;而其他依赖关系的注入,则考虑采用设值注入。

使用IoC容器的三个基本要点:

应用程序的各组件面向接口编程,这样就可以将组件之间的耦合关系提升到接口层次,从而有有利于项目后期的发展;

应用程序的各组件不再由程序主动创建,而是由Spring容器来负责产生并初始化;

Spring采用配置文件或注解来管理Bean的实现类、依赖关系,Spring容器则根据配置文件或注解,利用反射来创建实例,并为之注入依赖关系。

 面向切面编程(AOP)

面向切面编程(AOP)就是纵向的编程。比如业务A和业务B现在需要一个相同的操作,传统方法我们可能需要在A、B中都加入相关操作代码,而应用AOP就可以只写一遍代码,A、B共用这段代码。并且,当A、B需要增加新的操作时,可以在不改动原代码的情况下,灵活添加新的业务逻辑实现。

在实际开发中,比如商品查询、促销查询等业务,都需要记录日志、异常处理等操作,AOP把所有共用代码都剥离出来,单独放置到某个类中进行集中管理,在具体运行时,由容器进行动态织入这些公共代码。

AOP主要一般应用于签名验签、参数校验、日志记录、事务控制、权限控制、性能统计、异常处理等。

AOP涉及名词

切面(Aspect):共有功能的实现。如日志切面、权限切面、验签切面等。在实际开发中通常是一个存放共有功能实现的标准Java类。当Java类使用了@Aspect注解修饰时,就能被AOP容器识别为切面。

通知(Advice):切面的具体实现。就是要给目标对象织入的事情。以目标方法为参照点,根据放置的地方不同,可分为前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)与环绕通知(Around)5种。在实际开发中通常是切面类中的一个方法,具体属于哪类通知,通过方法上的注解区分。

连接点(JoinPoint):程序在运行过程中能够插入切面的地点。例如,方法调用、异常抛出等。Spring只支持方法级的连接点。一个类的所有方法前、后、抛出异常时等都是连接点。

切入点(Pointcut):用于定义通知应该切入到哪些连接点上。不同的通知通常需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的。

比如,在上面所说的连接点的基础上,来定义切入点。我们有一个类,类里有10个方法,那就产生了几十个连接点。但是我们并不想在所有方法上都织入通知,我们只想让其中的几个方法,在调用之前检验下入参是否合法,那么就用切点来定义这几个方法,让切点来筛选连接点,选中我们想要的方法。切入点就是来定义哪些类里面的哪些方法会得到通知。

目标对象(Target):那些即将切入切面的对象,也就是那些被通知的对象。这些对象专注业务本身的逻辑,所有的共有功能等待AOP容器的切入。

代理对象(Proxy):将通知应用到目标对象之后被动态创建的对象。可以简单地理解为,代理对象的功能等于目标对象本身业务逻辑加上共有功能。代理对象对于使用者而言是透明的,是程序运行过程中的产物。目标对象被织入共有功能后产生的对象。

织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。这个过程可以发生在编译时、类加载时、运行时。Spring是在运行时完成织入,运行时织入通过Java语言的反射机制与动态代理机制来动态实现。

Aspect Oriented Programming,面向切面编程,用于在模块化方面的横切关注点。AOP和OOP(Object Oriented Programming)互为补充,可以这么理解:面向对象编程是从静态角度纵向考虑程序结构,面向切面编程则是从动态角度横向考虑运行过程。比如一个日记记录的功能,代码往往水平的散落在所有对象中,与被散布的对象的核心功能没什么关系,这种散布在各个对象中的无关代码被称为“横切代码”,在OOP的设计中,它导致了大量代码的重复,从而不利于各个模块的复用。

简单的说,它是一个拦截器可以拦截一些过程,当一个方法执行,Spring AOP可以拦截一个方法的执行,在这个方法执行的前后添加一些功能。是一个典型代理模式的应用。

使用场景

日志记录、审计、声明式事务、安全性和缓存等。

总结

IoC,(Inverse of Control)控制反转,其包含两个内容:其一是控制,其二是反转。在程序中,被调用类的选择控制权从调用它的类中移除,转交给第三方裁决。这个第三方指的就是Spring的容器。IoC另解,依赖注入(Dependency Injection),调用类对被调用类的依赖关系由第三方注入,以移除调用类对被调用类的引用。

aop,面向切面编程(也叫面向方面):Aspect Oriented Programming(AOP),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。  AOP是OOP的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面(方面)编程。主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。   主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改 变这些行为的时候不影响业务逻辑的代码。 作者:佛系的工具人 https://www.bilibili.com/read/cv15072700/ 出处:bilibili

参考文章:https://blog.csdn.net/weixin_43687849/article/details/124257941

https://www.bilibili.com/read/cv15072700/

你可能感兴趣的:(spring ioc 和 aop)