【日积月累】Spring中的AOP与IOC相关问题详解

发布时间:2023年12月18日


文章所属专区 日积月累


1.前言

本文主要针对Spring中两大特性,AOP和IOC,并针对他们的使用常见,结合面试常见问题,实现代码,进行解析。

2.Spring AOP(面向切面编程)

在使用Java语言进行代码编写时,由于Java语言的特性,会有一些弊端,比如在处理一些不具有继承关系的一些类的公共行为时,只能在每个对象引用公共行为,会出现大量重复代码,会造成大量代码冗余,这样不仅浪费时间,也不方便维护,AOP的出现解决了这一个问题。

2.1 AOP的实现过程

Spring中的AOP基于代理模式,首先会自定义一个注解;
其次,定义一个切面(Aspect)类,在切面中定义切点和通知,切点(方法的拦截规则),在使用了这个注解的方法会被拦截下来,拦截下来之后;
最后可以进行前置通知、后置通知、异常通知、返回通知还是环绕通知等。

2.2 AOP代理模式的类型

代理类可以分为两类 动态代理(Dynamic Proxy)和静态代理(Static Proxy)Spring AOP(面向切面编程)中主要是运用了动态代理的方式来实现:在运行过程中通过反射机制动态创建而成,无需手动编写代码。

2.2.1JDK的动态代理

JDK动态代理是Spring AOP默认使用的方式,主要用于对实现了接口的类生成代理。JDK动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编制在一起。Prox则利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象

2.2.2CGLIB的动态代理

CGLIB(Code Generation Library)是针对类实现代理的,主要是对指定的类生成一个子类,覆盖其中的方法(继承)。CGLIB是一个强大的高性能,高质量的代码生成类库,可以在运行期扩展Java类与实现Java接口。CGLIB封装了asm,可以再运行期动态生成新class

2.2.3CGLIB与JDK的区别

cglib底层是基于继承被代理类来做代理的,而jdk则是通过接口的形式来做代理的。
jkd动态代理只提供接口的代理,不支持类的代理
如果代理类没有实现接口,那么Spring AOP会使用cglib来动态代理目标类

2.3AOP应用常见场景

比如日志记录,性能优化,权限控制,内容传递,错误处理,事务管理,限流等。

2.3.1日志记录

在Spring AOP中,可以使用@AspectJ注解定义一个切面,然后在切面方法中添加@Before或@After注解,用于在方法执行前后插入相应的日志记录逻辑

2.4对AOP的理解

AOP是Spring框架中最核心的两个点之一,它可以减少重复代码,降低模块间的耦合性,提高代码的可操作性和可维护性。在实际工作中,除了业务代码之外,还经常会接触到与业务无关的一些组件,比如日志,权限,事务等常见的核心服务组件,如果为每个业务代码单独添加这些组件,会出现大量的冗余代码,因此我们将这些公共的代码逻辑抽象出来成为一个切面,然后注入到具体业务中去。AOP就是通过这样一种方式,通过动态代理的方式,来对需要注入切面的对象进行代理,在进行调用时,直接将公共逻辑添加进去,而不需要修改原有的业务代码,在不改变原有业务代码的情况下做了代码功能的增强。

3.Spring IOC(Inversion of Control,控制反转)

在传统的软件设计过程中,通常由调用者来创建被调用者的实例。但在Spring中创建被调用者的工作不在由调用者来完成,这就是控制反转。IOC是一种设计思想,即把原本在程序中手动创建对象的控制权交给了Spring框架中的IOC容器,让它去创建和管理这些对象。在Spring中实现IOC主要依靠DI(Dependency Injection 依赖注入) 来实现。

3.1使用Spring IOC 的好处

在 Spring 中, IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。

  1. 由于资源不再由使用资源的双方管理,因此,资源可以集中管理,实现资源的可配置和易管理
  2. 降低了使用资源双方的依赖程度(低耦合度)。

3.2使用Spring IOC 依赖注入的方式

3.2.1通过xml文件注入

属性注入(property)、构造器注入(constructor-arg)、自动装配通过对bean的autowrite属性指定(byName、byType)

3.2.2通过注解注入

这种方式后来在 SpringBoot 中常用 ,@autowrite @resource @component等

3.3 IOC的理解

IOC 控制反转:

在没有使用IOC容器之前,都是由程序员来控制对象,而有了IOC容器之后,则由IOC容器来控制对象;
控制的是实现过程中所需要的对象以及依赖的对象;
在没有使用IOC之前,我们都需要主动在对象中创建依赖的对象,这种正转的,而有了IOC之后,依赖的对象由IOC创建后注入到对象中,由主动创建变成了被动接受,这是反转;
IOC是一种思想,DI(依赖注入:把对应的属性的值注入到对象)是具体的实现方式 @AutoWried

3.4 IOC容器的创建过程

IOC 容器(Spring用来实现IOC的载体,实际是个Map(Key,value),Map中存放的是各种对象):

在Spring中一般存在三级缓存,singletonObject存放完整的Bean对象,整个Bean的生命周期,从创建到使用到销毁全部都由容器来控制。

1.IOC容器的创建(beanFactory根接口的DeafultListableBeanFactory)优先创建bean工厂,向bean工厂设置一些属性(BeanPostProcessor,Aware接口的子类)等属性
2.加载解析bean对象,准备创建的定义对象beanDefinition(会涉及到xml或者注解的解析过程)
3.BeanFactoryProcessor的处理,此处是扩展点!!!(PlaceHolderConfigurSupport 处理占位符,ConfigurationClassPostProssor)
4.BeanPostProcessor的注册功能,方便后续对bean对象完成具体的扩展功能
5.通过反射的方式将BeanDefinition对象实例化成具体的bean对象
6.bean对象的初始化过程(填充属性,调用Aware子类的方法,调用BeanPostProcessor前置处理方法,调用init-method方法,调用BeanPostProcessor的后置处理方法–Bean的生命周期)
7.生成完整的bean对象,通过getBean方法可以直接获取
8.销毁过程

以上就是我对于ioc的整体理解,包含一些细节,如果有什么问题,请小伙伴指点一下
总结:
spring中的Bean都是通过反射生产的,其中包含了很多的扩展点,比如常见的对BeanFactory的扩展,对Bean的扩展,此外,ioc中最核心的就是填充具体Bean的属性和Bean的生命周期

3.5谈谈Spring IOC的底层实现

底层实现:工作原理,过程,数据结构,流程,设计模式,设计思想
方法:
createBeanFactory
getBean
doGetBean
createBean
doCreateBean
1.先通过creatBeanFactory方法中的DeafultListableBeanFactory创建一个Bean工厂
2.开始循环创建对象,因为容器中的Bean都是单例的,所以优先通过getBean,doGetBean从容器中查找,找不到的话,
3.通过createBean,doCreateBean方法,以反射的方式创建对象,一般情况下使用无参的构造方法(getDeclaredConstructor,newInstance)
4.通过polulateBean进行对象的属性填充
5.进行其他的初始化操作(initializingBean)

IOC中Bean的生命周期

在这里插入图片描述
1.通过反射实例化Bean对象:通过反射的方式生成对象
2.通过polulateBean设置对象属性:populateBean(),循环依赖的问题(三级缓存)
3.调用aware接口的相关方法:invokeAwareMethod(完成BeanName,BeanFactory,BeanClassLoader对象的属性设置)
4.调用BeanPostProcessor中的前置处理方法(ApplicationContextPostProcessor,设置Application的Context,Environment,ResourceLoader等对象)
5.调用init-method方法:invokeInitMethod() 判断是否实现了initiazingBean接口,如果有就调用afterPorpertiesSet()方法,没有就不调用
6.调用BeanPostProcessor的后置处理方法:Spring的AOP就是在此处实现的 AbstractAutoProxyCreator()
7.获取到完整的对象,可以通过getBean的方式来进行对象的获取
8.销毁流程:1.判断是否实现了DispoableBean接口2.调用destoryMethod()方法。

4.参考

谈谈对IOC的理解
Spring AOP的理解与使用
面试被问了几百遍的 IoC 和 AOP ,还在傻傻搞不清楚?

给个三连吧 谢谢谢谢谢谢了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

文章来源:https://blog.csdn.net/qq_43238568/article/details/134938324
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。