Spring面试题

破局之路课程 2024-03-20 13:06:53
Spring Bean实例化流程

在 Spring 框架中,Bean 的实例化流程通常包括以下步骤:

加载配置文件:Spring 容器会加载配置文件,包括 XML 配置文件、注解配置等,用于定义 Bean 的信息。解析配置文件:Spring 容器会解析配置文件,识别出配置中定义的 Bean,以及它们之间的依赖关系。实例化 Bean:Spring 容器根据配置文件中的信息,实例化每个 Bean。这通常是通过调用 Bean 的构造方法来创建 Bean 对象的过程。设置 Bean 的属性:一旦 Bean 对象被实例化,Spring 容器会根据配置文件中的属性设置,通过调用相应的 setter 方法来设置 Bean 的属性。Bean 的初始化:如果配置了初始化方法(例如通过 init-method 属性),Spring 容器会在 Bean 的所有属性设置完成后调用初始化方法。Bean 的使用:一旦所有 Bean 实例化、属性设置和初始化都完成,Bean 就可以被应用程序使用了。Bean 的销毁:如果配置了销毁方法(例如通过 destroy-method 属性),Spring 容器在应用程序关闭时会调用 Bean 的销毁方法进行清理工作。

这是 Spring Bean 的一般实例化流程,具体的实现细节可能会根据不同的配置方式和 Bean 类型而有所不同。希望这个回答能够帮助你理解 Spring Bean 的实例化过程。

Bean生命周期

在 Spring 框架中,Bean 的生命周期可以分为以下阶段:

实例化阶段:Spring 容器根据配置信息实例化 Bean 对象,通常是通过调用 Bean 的构造方法来创建实例。属性设置阶段:Spring 容器会注入 Bean 的属性,可以通过构造函数注入、Setter 方法注入或字段注入等方式来设置 Bean 的属性。初始化阶段:如果 Bean 实现了 InitializingBean 接口,或者在配置文件中通过 init-method 指定了初始化方法,Spring 容器会在 Bean 的所有属性设置完成后调用初始化方法进行一些初始化操作。Bean 可用阶段:在初始化完成后,Bean 就可以被应用程序使用了,可以执行各种业务逻辑。销毁阶段:当应用程序关闭时,Spring 容器会调用 Bean 的销毁方法,可以通过实现 DisposableBean 接口或在配置文件中通过 destroy-method 指定销毁方法来进行清理操作。

在整个生命周期中,Spring 容器负责管理 Bean 的创建、初始化和销毁等过程,开发人员可以通过配置文件或注解来定义 Bean 的生命周期行为,以满足不同的需求。

总的来说,Spring Bean 的生命周期可以概括为实例化、属性设置、初始化、可用和销毁等阶段。希望这个回答对你有帮助。

Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

Bean自身的方法: 这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法Bean级生命周期接口方法: 这个包括了BeanNameAware、BeanFactoryAware、ApplicationContextAware;当然也包括InitializingBean和DiposableBean这些接口的方法(可以被@PostConstruct和@PreDestroy注解替代)容器级生命周期接口方法: 这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。工厂后处理器接口方法: 这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

具体而言,流程如下

如果 BeanFactoryPostProcessor 和 Bean 关联, 则调用postProcessBeanFactory方法.(即首先尝试从Bean工厂中获取Bean)如果 InstantiationAwareBeanPostProcessor 和 Bean 关联,则调用postProcessBeforeInstantiation方法根据配置情况调用 Bean 构造方法实例化 Bean。利用依赖注入完成 Bean 中所有属性值的配置注入。如果 InstantiationAwareBeanPostProcessor 和 Bean 关联,则调用postProcessAfterInstantiation方法和postProcessProperties调用xxxAware接口 (上图只是给了几个例子)第一类Aware接口如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。如果 Bean 实现了 BeanClassLoaderAware 接口,则 Spring 调用 setBeanClassLoader() 方法传入classLoader的引用。如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。第二类Aware接口如果 Bean 实现了 EnvironmentAware 接口,则 Spring 调用 setEnvironment() 方法传入当前 Environment 实例的引用。如果 Bean 实现了 EmbeddedValueResolverAware 接口,则 Spring 调用 setEmbeddedValueResolver() 方法传入当前 StringValueResolver 实例的引用。如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。...如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。(或者有执行@PostConstruct注解的方法)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。如果在 <bean> 中指定了该 Bean 的作用范围为 scope="singleton",则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 <bean> 中指定了该 Bean 的作用范围为 scope="prototype",则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;(或者有执行@PreDestroy注解的方法)如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。

Spring启动流程

https://blog.csdn.net/dreambyday/article/details/125473596

Spring 框架在启动过程中会执行一系列步骤来初始化应用程序上下文并准备好处理请求。以下是 Spring 启动的主要流程:

加载配置文件:Spring 应用程序启动时会加载配置文件,包括 XML 配置文件、注解配置类等。创建应用程序上下文:Spring 容器在启动时会创建应用程序上下文,该上下文包含了应用程序中所有 Bean 的定义、依赖关系和配置信息。扫描组件:Spring 容器会扫描应用程序中的组件,包括注解标记的 Bean、配置类等,并将它们注册到应用程序上下文中。实例化 Bean:Spring 容器根据配置信息实例化 Bean 对象,可以通过构造函数注入、Setter 方法注入或字段注入等方式来设置 Bean 的属性。依赖注入:Spring 容器会自动解析 Bean 之间的依赖关系,并将依赖的 Bean 注入到目标 Bean 中。执行 Bean 的生命周期回调:如果 Bean 实现了特定的接口(如 InitializingBean 和 DisposableBean),Spring 容器会在适当的时机调用 Bean 的初始化方法和销毁方法。执行自定义初始化方法:如果在配置文件中通过 @PostConstruct 注解或 init-method 指定了初始化方法,Spring 容器会在实例化和依赖注入完成后调用这些方法。应用程序准备就绪:当所有 Bean 实例化、依赖注入和初始化完成后,应用程序就处于可用状态,可以处理请求和执行业务逻辑。处理请求:Spring 应用程序启动后,可以接收和处理来自客户端的请求,调用相应的 Bean 处理请求并返回结果。

总的来说,Spring 启动流程包括加载配置文件、创建应用程序上下文、注册 Bean、依赖注入、执行生命周期回调等步骤,最终使应用程序准备好接收和处理请求。

AOP核心概念Jointpoint(连接点):具体的切面点点抽象概念,可以是在字段、方法上,Spring中具体表现形式是PointCut(切入点),仅作用在方法上。Advice(通知): 在连接点进行的具体操作,如何进行增强处理的,分为前置、后置、异常、最终、环绕五种情况。目标对象:被AOP框架进行增强处理的对象,也被称为被增强的对象。AOP代理:AOP框架创建的对象,简单的说,代理就是对目标对象的加强。Spring中的AOP代理可以是JDK动态代理,也可以是CGLIB代理。Weaving(织入):将增强处理添加到目标对象中,创建一个被增强的对象的过程

总结为一句话就是:在目标对象(target object)的某些方法(jointpoint)添加不同种类的操作(通知、增强操处理),最后通过某些方法(weaving、织入操作)实现一个新的代理目标对象。

原理

Spring AOP是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP就会使用JDK动态代理去创建代理对象;而对于没有实现接口的对象,就无法使用JDK动态代理,转而使用CGlib动态代理生成一个被代理对象的子类来作为代理。

当然也可以使用AspectJ,Spring AOP中已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。使用AOP之后我们可以把一些通用功能抽象出来,在需要用到的地方直接使用即可,这样可以大大简化代码量。我们需要增加新功能也方便,提高了系统的扩展性。日志功能、事务管理和权限管理等场景都用到了AOP。

实现 AOP 的技术,主要分为两大类:

静态代理指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;编译时编织(特殊编译器实现)类加载时编织(特殊的类加载器实现)。动态代理在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。JDK 动态代理JDK Proxy 是 Java 语言自带的功能,无需通过加载第三方类实现;Java 对 JDK Proxy 提供了稳定的支持,并且会持续的升级和更新,Java 8 版本中的 JDK Proxy 性能相比于之前版本提升了很多;JDK Proxy 是通过拦截器加反射的方式实现的;JDK Proxy 只能代理实现接口的类;JDK Proxy 实现和调用起来比较简单;CGLIBCGLib 是第三方提供的工具,基于 ASM 实现的,性能比较高;CGLib 无需通过接口来实现,它是针对类实现代理,主要是对指定的类生成一个子类,它是通过实现子类的方式来完成调用的。

使用场景日志打印共同业务处理监控事务

Spring中的bean的作用域有哪些?singleton:唯一bean实例,Spring中的bean默认都是单例的。prototype:每次请求都会创建一个新的bean实例。request:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。session:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。global-session:全局session作用域,仅仅在基于Portlet的Web应用中才有意义,Spring5中已经没有了。Portlet是能够生成语义代码(例如HTML)片段的小型Java Web插件。它们基于Portlet容器,可以像Servlet一样处理HTTP请求。但是与Servlet不同,每个Portlet都有不同的会话。

Spring mvc工作原理

流程说明:

1.客户端(浏览器)发送请求,直接请求到DispatcherServlet。

2.DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。

3.解析到对应的Handler(也就是我们平常说的Controller控制器)。

4.HandlerAdapter会根据Handler来调用真正的处理器来处理请求和执行相对应的业务逻辑。

5.处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是逻辑上的View。

6.ViewResolver会根据逻辑View去查找实际的View。

7.DispatcherServlet把返回的Model传给View(视图渲染)。

8.把View返回给请求者(浏览器)。

如何自定义Spring Boot Starter?实现功能添加Properties@Data@ConfigurationProperties(prefix = "com.pdai")public DemoProperties { private String version; private String name;}添加AutoConfiguration@Configuration@EnableConfigurationProperties(DemoProperties.class)public DemoAutoConfiguration { @Bean public com.pdai.demo.module.DemoModule demoModule(DemoProperties properties){ com.pdai.demo.module.DemoModule demoModule = new com.pdai.demo.module.DemoModule(); demoModule.setName(properties.getName()); demoModule.setVersion(properties.getVersion());return demoModule; }}添加spring.factory

在META-INF下创建spring.factory文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.pdai.demospringbootstarter.DemoAutoConfigurationinstall

0 阅读:0

破局之路课程

简介:感谢大家的关注