Spring Bean的scope(作用域)有哪些
Bean 的 scope(作用域)定义了 Bean 实例的生命周期及可见范围,常见的 Bean scope:
*Singleton(单例):在整个应用程序中只存在一个 Bean 实例。默认作用域,Spring 容器中只会创建一个 Bean 实例,并在容器的整个生命周期中共享该实例。
*Prototype(原型):每次请求时都会创建一个新的 Bean 实例。次从容器中获取该 Bean 时都会创建一个新实例,适用于状态非常瞬时的 Bean。
*Request(请求):每个 HTTP 请求都会创建一个新的 Bean 实例。仅在 Spring Web 应用程序中有效,每个 HTTP 请求都会创建一个新的 Bean 实例,适用于 Web 应用中需求局部性的 Bean。
*Session(会话):Session 范围内只会创建一个 Bean 实例。该 Bean 实例在用户会话范围内共享,仅在 Spring Web 应用程序中有效,适用于与用户会话相关的 Bean。
*Application:当前 ServletContext 中只存在一个 Bean 实例。仅在 Spring Web 应用程序中有效,该 Bean 实例在整个 ServletContext 范围内共享,适用于应用程序范围内共享的 Bean。
*WebSocket(Web套接字):在 WebSocket 范围内只存在一个 Bean 实例。仅在支持 WebSocket 的应用程序中有效,该 Bean 实例在 WebSocket 会话范围内共享,适用于 WebSocket 会话范围内共享的 Bean。
*Custom scopes(自定义作用域):Spring 允许开发者定义自定义的作用域,通过实现 Scope 接口来创建新的 Bean 作用域。
讲一讲AOP的实现方式
Spring的AOP实现原理其实很简单,就是通过动态代理实现的。如果我们为Spring的某个bean配置了切面,那么Spring在创建这个bean的时候,实际上创建的是这个bean的一个代理对象,我们后续对bean中方法的调用,实际上调用的是代理类重写的代理方法。而Spring的AOP使用了两种动态代理,分别是JDK的动态代理,以及CGLib的动态代理。
*基于JDK的动态代理:Spring默认使用JDK的动态代理实现AOP,类如果实现了接口,Spring就会使用这种方式实现动态代理。熟悉Java语言的应该会对JDK动态代理有所了解。JDK实现动态代理需要两个组件,首先第一个就是InvocationHandler接口。我们在使用JDK的动态代理时,需要编写一个类,去实现这个接口,然后重写invoke方法,这个方法其实就是我们提供的代理方法。然后JDK动态代理需要使用的第二个组件就是Proxy这个类,我们可以通过这个类的newProxyInstance方法,返回一个代理对象。生成的代理类实现了原来那个类的所有接口,并对接口的方法进行了代理,我们通过代理对象调用这些方法时,底层将通过反射,调用我们实现的invoke方法。
*基于CGLIB的动态代理:JDK的动态代理存在限制,那就是被代理的类必须是一个实现了接口的类,代理类需要实现相同的接口,代理接口中声明的方法。若需要代理的类没有实现接口,此时JDK的动态代理将没有办法使用,于是Spring会使用CGLib的动态代理来生成代理对象。CGLib直接操作字节码,生成类的子类,重写类的方法完成代理。
JDK Proxy和CGLib还有别的实现AOP的方式吗?
静态代理:通过 AOP 框架提供的命令进行编译,从而在编译阶段生成 AOP 代理类。这种方式也被称为编译时增强。静态代理包括编译时编织和类加载时编织两种方式。
讲一讲对Spring Boot的理解,以及为什么要用Spring Boot?
在使用Spring框架进行开发的过程中,需要配置很多Spring框架包的依赖,如spring-core、spring-bean、spring-context等,而这些配置通常都是重复添加的,而且需要做很多框架使用及环境参数的重复配置,如开启注解、配置日志等。
Spring Boot致力于弱化这些不必要的操作,提供默认配置,当然这些默认配置是可以按需修改的,快速搭建、开发和运行Spring应用。
Spring Boot 的主要优点:
*简化开发:Spring Boot通过约定大于配置的原则和自动化配置,大大简化了Java应用程序的开发和部署过程。开发者无需处理繁琐的配置,可以快速搭建项目并专注于业务逻辑的实现。
*集成性强:Spring Boot提供了大量的起步依赖,涵盖了各种常见的库、框架和组件,使得集成第三方库和服务变得更加容易。同时,Spring Boot内置了大量的功能,如内置容器、安全性、监控等,可以快速集成这些功能到项目中。
*独立运行:Spring Boot应用程序可以独立运行,内嵌了常用的Web服务器,如Tomcat、Jetty等,使得部署变得简单。开发者无需额外配置Web服务器,只需执行一个可执行的JAR文件即可启动应用。
*微服务友好:Spring Boot非常适合构建微服务架构,其轻量级、模块化的特性使得微服务之间的通信和部署变得更加方便。结合Spring Cloud等微服务组件,可以更好地实现微服务架构下的各种功能。
讲一讲Spring Boot简化配置具体是如何简化的?
Spring 虽然使Java EE轻量级框架,但由于其繁琐的配置,一度被人认为是“配置地狱”。各种XML、Annotation配置会让人眼花缭乱,而且配置多的话,如果出错了也很难找出原因。Spring Boot更多的是采用 Java Config 的方式,对 Spring 进行配置。
举个例子:我新建一个类,但是我不用 @Service注解,也就是说,它是个普通的类,那么我们如何使它也成为一个 Bean 让 Spring 去管理呢?只需要@Configuration 和@Bean两个注解即可,如下:
public class TestService {
public String sayHello () {
return "Hello Spring Boot!";
}
}
1
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JavaConfig {
@Bean
public TestService getTestService() {
return new TestService();
}
}
@Configuration表示该类是个配置类,@Bean表示该方法返回一个 Bean。这样就把TestService作为 Bean 让 Spring 去管理了,在其他地方,我们如果需要使用该 Bean,和原来一样,直接使用@Resource注解注入进来即可使用,非常方便。
@Resource
private TestService testService;
另外,部署配置方面,原来 Spring 有多个 xml 和 properties配置,在 Spring Boot 中只需要个 application.yml即可。
Spring Boot是通过什么实现的约定大于配置?
Spring Boot通过「自动化配置」和「起步依赖」实现了约定大于配置的特性。
*自动化配置:Spring Boot根据项目的依赖和环境自动配置应用程序,无需手动配置大量的XML或Java配置文件。例如,如果项目引入了Spring Web MVC依赖,Spring Boot会自动配置一个基本的Web应用程序上下文。
*起步依赖:Spring Boot提供了一系列起步依赖,这些依赖包含了常用的框架和功能,可以帮助开发者快速搭建项目。通过引入适合项目需求的起步依赖,开发者可以快速构建出符合要求的应用程序,减少了配置的复杂度