84道Spring高频题整理(附答案背诵版)

解释一下Spring 框架?

Spring框架是一个开源的企业级应用开发框架,由Rod Johnson创建,并于2003年首次发布。Spring 是在全方位提供企业级服务的基础上,用Java实现的。Spring的核心思想是使现代Java开发更加简单。

Spring框架以其灵活性和透明性闻名,几乎可以用在任何Java环境中。Spring的核心是控制反转(IoC)或依赖注入(DI)和面向切面编程(AOP)。

以下是Spring框架的主要特点:

  1. 依赖注入:Spring框架通过依赖注入的方式来管理对象。这样有助于降低对象之间的耦合度,并提高代码的可测试性和可维护性。
  2. 面向切面编程:Spring支持面向切面编程,这样可以把业务逻辑和系统服务分离开来。比如日志记录、事务管理、安全等,这些可以通过AOP的方式插入到业务逻辑中。
  3. 事务管理:Spring提供了一套事务管理接口,可以和多种事务管理平台进行集成。
  4. MVC框架:Spring还包含了一个灵活的MVC Web应用框架,用于搭建Web应用。

Spring 中常用的注解有哪些?

Spring框架中有一些常见的注解,这些注解大大简化了Java开发人员的工作。以下是一些常见的Spring注解:

  1. @Component:这是一个通用的注解,表示该类是一个Spring管理的组件。所有的Spring注解,例如@Service、@Repository和@Controller,都是@Component的特化形式。
  2. @Autowired:这个注解用于自动注入依赖。Spring会查找并注入标记为@Component的类,这个类的类型与@Autowired注解字段的类型相匹配。
  3. @Service:这个注解用于标记服务层的组件。
  4. @Repository:这个注解用于标记数据访问组件,即DAO组件。
  5. @Controller:这个注解用于标记控制器组件,主要用在Spring MVC中。
  6. @RequestMapping:这个注解用于指定处理器函数或者控制器类能处理的URL路径。
  7. @PathVariable:这个注解用于处理URL中的动态部分,并将其传递给处理器函数作为参数。
  8. @RequestParam:这个注解用于从请求参数中获取值。
  9. @ResponseBody:这个注解用于将返回值转化为HTTP响应体。
  10. @Configuration:这个注解表明该类包含一个或多个@Bean方法,并且Spring容器需要处理这些方法以生成bean定义。
  11. @Bean:这个注解用于将方法的返回值注册为Spring应用上下文中的bean。

Spring 框架的好处?

Spring框架为企业级Java开发带来了很多好处:

  1. 便捷的依赖管理:Spring框架的核心是控制反转(IoC)和依赖注入(DI),这让组件间的依赖关系变得更加清晰,代码更加松耦合。
  2. 面向切面的编程:Spring的AOP模块让关注点的分离变得简单,提升了程序的可重用性。例如,事务管理、日志记录、权限控制等都可以被定义为切面,并在适当的时机应用到业务逻辑代码上。
  3. 事务管理:Spring提供了一套事务管理接口,可以与多种事务管理平台进行集成,使得事务管理变得非常方便。
  4. 强大的Web MVC:Spring的Web MVC框架是一个设计良好的Web层框架,它完全整合了其他Spring组件。
  5. 与主流技术的集成:Spring提供了对主流对象关系映射(ORM)框架的集成,如Hibernate、MyBatis等,也提供了对Java EE标准的支持,如JMS、EJB、JPA等。
  6. 测试便捷:Spring的测试模块提供了强大的单元测试和集成测试功能,可以方便地进行测试驱动开发(TDD)。

Spring 的主要模块有哪些?

Spring框架主要由以下模块组成:

  1. Spring Core:这是Spring框架的核心模块,提供了控制反转(IoC)和依赖注入(DI)功能。

  2. Spring AOP:面向切面编程(AOP)模块支持面向切面编程,允许定义方法拦截器和切点来解决企业级应用的横切关注点。

  3. Spring DAO:数据访问对象(DAO)模块为数据访问提供了JDBC抽象层,消除了常见的数据访问相关的重复性代码。

  4. Spring ORM:对象关系映射(ORM)模块为流行的ORM API,如JPA,JDO,Hibernate,MyBatis等,提供了集成层。

  5. Spring Web MVC:这是一个用于创建Web应用的模块。Spring的Web模块是一个全功能的MVC模块,提供了更强大和更灵活的Web应用开发选项。

  6. Spring Context:这个模块支持国际化(i18n)等企业级服务,提供了框架式的方式来管理bean和bean之间的依赖关系。

  7. Spring Test:这个模块支持对Spring组件的JUnit或TestNG测试。

解释一下Spring IOC ?

Spring的控制反转(IoC)容器是Spring框架核心的一部分。IoC容器负责实例化、配置和装配应用中所需的对象。这些对象在Spring中被称为beans,它们是应用的主体部分和应用业务逻辑的实现。

Spring IoC容器的主要功能包括:

  1. Bean实例化:Spring IoC容器会负责创建对象实例。你只需要在配置文件中定义需要的对象,以及这些对象的属性和依赖关系,然后Spring IoC容器就会自动创建这些实例。

  2. 依赖注入:Spring IoC容器通过依赖注入(DI)的方式来管理对象的依赖关系。这意味着,如果一个对象需要另一个对象才能正确工作,那么Spring IoC容器会自动把所需的对象注入到依赖它的对象中。

  3. Bean配置:Spring IoC容器允许你在配置文件中定义对象的各种属性。这意味着,你可以在配置文件中改变对象的行为,而无需修改对象的源代码。

  4. 生命周期管理:Spring IoC容器还负责管理对象的生命周期。这包括对象的创建、初始化、使用和销毁。

Spring IoC容器的这些功能,使得应用的组件可以更容易地解耦合,并且在修改、测试和重用时更加灵活。

例如,你可能有一个BookService类,它依赖于BookRepository接口的某个实现。在没有Spring的情况下,你需要手动创建BookRepository的实现,并将其传递给BookService。但是在Spring中,你只需要在BookService中注解@Autowired,然后Spring IoC容器就会自动创建一个BookRepository的实现,并注入到BookService中。

@Service
public class BookService {
    private final BookRepository bookRepository;

    @Autowired
    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    // ...
}

在这个例子中,Spring IoC容器管理了BookRepository的生命周期,并在需要的时候将其注入到BookService中,这样你就不需要手动管理这些依赖了。

Spring IOC 的好处?

Spring IoC(控制反转)提供了很多好处,主要包括以下几点:

  1. 解耦:通过IoC,对象之间的依赖关系由Spring框架负责管理和装配,而不是由对象自己控制。这样可以降低代码的耦合度,使得代码更加灵活和易于维护。
  2. 代码简化:Spring IoC容器负责创建和管理对象,我们只需要简单地声明依赖即可。这大大简化了代码,使得开发更加快捷。
  3. 易于测试:由于依赖注入,我们可以很容易地用mock对象替换掉真实的依赖,进行单元测试。
  4. 配置集中:Spring IoC容器可以集中管理所有bean的配置信息,使得配置更加集中和一致。
  5. 生命周期管理:Spring IoC容器负责管理bean的完整生命周期,从创建到销毁,包括初始化和清理等操作。
  6. 延迟加载/懒加载:Spring IoC容器默认情况下,只有当应用实际请求一个bean时,才会创建这个bean,这叫做懒加载或延迟加载,可以提高应用的启动速度。

什么是Spring 中的 BeanFactory ?

BeanFactory 是 Spring 框架中的基础类型的工厂模式接口,它提供了高级的 IoC(Inversion of Control)功能来管理你的 beans。它主要负责初始化、配置和管理 beans,以及解决依赖关系。

当你在 Spring 的配置文件中定义一个 bean,那么 Spring IoC 容器就会通过 BeanFactory 创建一个对象(bean 实例),并根据你的配置管理这个对象的生命周期和依赖关系。

在 Spring 中,有许多 BeanFactory 的实现,如 XmlBeanFactory、DefaultListableBeanFactory 等。但在实际应用中,我们通常使用 ApplicationContext,它是 BeanFactory 的子接口,提供了更多高级特性。

例如,如果我们在 Spring 的配置文件中定义了一个名为 "myBean" 的 bean,我们可以使用 BeanFactory 来获取这个 bean 的实例:

BeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
MyBean myBean = (MyBean) factory.getBean("myBean");

在这个例子中,"myBean" 是在 XML 配置文件中定义的 bean 的 id,getBean() 方法用于从 BeanFactory 中获取一个 bean 的实例。

什么是Spring 中的 ApplicationContext ?

ApplicationContext 是 Spring 框架中的一个核心接口,它是 BeanFactory 的子接口,也就是说,它包含了 BeanFactory 的所有功能。但是,ApplicationContext 提供了更多面向应用的功能,比如更方便的集成 Spring 的 AOP 特性,消息资源处理(用于 i18n)、事件发布、应用层的上下文(如 WebApplicationContext)等。

当启动一个 Spring 应用时,它会创建一个 ApplicationContext 实例,然后由这个实例负责初始化和配置应用中的所有对象(beans)。ApplicationContext 通过读取配置元数据(可以是 XML 文件、Java 注解、Java 代码等)来管理这些 beans 的生命周期和依赖关系。

在实际开发中,我们通常使用 ApplicationContext 的一些常见实现,如 ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext 等。

例如,我们可以通过 ClassPathXmlApplicationContext 来加载 classpath 下的一个 XML 配置文件:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean myBean = (MyBean) context.getBean("myBean");

在这个例子中,"myBean" 是在 XML 配置文件中定义的 bean 的 id,getBean() 方法用于从 ApplicationContext 中获取一个 bean 的实例。

Spring 常用的 ApplicationContext 有哪些?

Spring 提供了几种常用的 ApplicationContext 实现,来满足不同的环境和需求:

  1. ClassPathXmlApplicationContext:这是最常用的 ApplicationContext 实现。它从类路径下的一个或多个 XML 配置文件中加载上下文定义,支持在实际应用中的各种环境。

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    
  2. FileSystemXmlApplicationContext:它也是一个常用的 ApplicationContext 实现。它从文件系统的某个位置加载上下文定义。

    ApplicationContext context = new FileSystemXmlApplicationContext("D:/applicationContext.xml");
    
  3. AnnotationConfigApplicationContext:它用于基于 Java 的配置类,而非 XML 文件来加载上下文定义。适用于全注解的项目,或者对源代码有控制的环境。

    ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    
  4. WebApplicationContext:它是专为 Web 应用而准备的,是个接口,分别有两个实现:XmlWebApplicationContext 和 AnnotationConfigWebApplicationContext,可以分别从 XML 文件或者注解配置中加载 Spring 应用上下文。

以上就是 Spring 常用的 ApplicationContext 实现。根据项目的需要,我们可以选择不同的 ApplicationContext 实现。

Spring 中 BeanFactory 和 ApplicationContext 的区别有哪些?

BeanFactory 和 ApplicationContext 都是 Spring 容器的核心接口,它们都可以用来获取、配置和管理 bean。但是,ApplicationContext 提供了更多高级特性,以下是它们的一些主要区别:

  1. 功能:BeanFactory 是最基本的容器,提供了完整的 IoC 服务支持。而 ApplicationContext 是 BeanFactory 的子接口,除了拥有 BeanFactory 的全部功能外,还添加了大量企业级的特性,如国际化支持、事件机制、更便捷的资源访问等。

  2. 初始化:当你创建一个 BeanFactory 实例时,它并不会立即初始化 bean,只有当你尝试获取一个 bean 时,才会触发 bean 的创建和依赖注入。而 ApplicationContext 在启动时就会创建所有的 singleton bean。这就意味着,ApplicationContext 启动会比 BeanFactory 慢,但获取 bean 的速度会更快。

  3. 资源访问:ApplicationContext 提供了一种更方便的方式来访问资源,如图片、音频、视频等。

  4. AOP 集成:ApplicationContext 更容易集成 Spring 的 AOP 特性。

  5. 消息资源处理:ApplicationContext 提供了一种统一的方式来加载消息资源,这对于国际化处理非常有用。

  6. Web 应用支持:ApplicationContext 提供了一种准备好的方式来构建 Web 应用。例如,它可以读取 Web.xml 中的参数,并将它们作为 bean 的属性。

总的来说,ApplicationContext 是一个更完整、更强大的容器,适合大多数应用场景。而 BeanFactory 更轻量级,适合资源有限、需要更精细控制的场景。

说一说Spring 获取 ApplicationContext 的方法?

在 Spring 中,我们可以通过多种方式获取 ApplicationContext 对象。以下是一些常见的方法:

  1. 在普通类中:如果你的类是由 Spring 管理的,你可以通过 @Autowired 注解将 ApplicationContext 注入到你的类中。

    @Autowired
    private ApplicationContext context;
    
  2. 在 Spring MVC 控制器中:在 Spring MVC 控制器中,你可以通过实现 ApplicationContextAware 接口来获取 ApplicationContext。

    public class MyController implements ApplicationContextAware {
        private ApplicationContext context;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) {
            this.context = applicationContext;
        }
    }
    
  3. 在 Spring Boot 应用中:在 Spring Boot 应用中,你可以在 main 方法中保存 ApplicationContext 到一个静态变量中。

    public class Application {
        private static ApplicationContext context;
    
        public static void main(String[] args) {
            context = SpringApplication.run(Application.class, args);
        }
    }
    
  4. 在配置类中:在 Java 配置类中,你可以直接将 ApplicationContext 作为一个 @Bean 方法的参数。

    @Configuration
    public class AppConfig {
        @Bean
        public MyBean myBean(ApplicationContext context) {
            // ...
        }
    }
    

以上就是在不同场景中获取 ApplicationContext 的一些方法。获取到 ApplicationContext 后,你就可以使用它来获取、查询和操作 bean 了。

解释一下Spring 依赖注入?

依赖注入(Dependency Injection,简称 DI)是 Spring 框架的核心功能之一。依赖注入是一种实现控制反转(Inversion of Control,简称 IoC)的技术,它可以帮助我们解耦代码,并提高代码的可测试性和可维护性。

依赖注入的基本思想是,一个类不应该自己去创建它依赖的对象,而应该由外部(如 Spring 容器)来负责创建和注入这些依赖对象。

例如,假设我们有一个 UserService 类,它依赖于一个 UserRepository 接口。在没有使用依赖注入的情况下,我们可能需要在 UserService 中自己去创建一个 UserRepository 的实现类:

public class UserService {
    private UserRepository userRepository = new UserRepositoryImpl();

    // ...
}

这样的代码存在一些问题:首先,UserService 与 UserRepositoryImpl 耦合度高,如果我们想替换另一个 UserRepository 的实现,就需要修改 UserService 的代码;其次,这样的代码很难进行单元测试,因为我们无法模拟 UserRepository。

使用依赖注入后,我们可以让 Spring 容器来创建 UserRepository 的实现类,并注入到 UserService 中:

@Service
public class UserService {
    private UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // ...
}

这样,UserService 就不再直接依赖于 UserRepositoryImpl,而是依赖于 UserRepository 接口。当我们需要替换 UserRepository 的实现,或者进行单元测试时,都可以更加容易地操作。

Spring 依赖注入的方式有哪些?

Spring 框架支持三种主要的依赖注入方式:

  1. 构造器注入:这是最常用的依赖注入方式。在这种方式中,我们会在类的构造器中声明依赖,然后 Spring 在创建这个 bean 时,会通过构造器参数将依赖注入进来。这种方式的优点是,可以确保 bean 的不变性和必要性,因为一旦 bean 被创建,它的依赖就不能被改变,而且必须提供所有的依赖。

    @Service
    public class UserService {
        private UserRepository userRepository;
    
        @Autowired
        public UserService(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        // ...
    }
    
  2. Setter 注入:在这种方式中,我们会为每个依赖提供一个 setter 方法,然后 Spring 在创建 bean 时,通过调用这些 setter 方法来注入依赖。这种方式的优点是,可以在 bean 创建后改变它的依赖,但也可能导致 bean 的状态不一致。

    @Service
    public class UserService {
        private UserRepository userRepository;
    
        @Autowired
        public void setUserRepository(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        // ...
    }
    
  3. 字段注入:在这种方式中,我们直接在字段上使用 @Autowired 注解,然后 Spring 会在创建 bean 时,自动注入这个字段的依赖。这种方式的优点是,代码更简洁,但缺点是,我们不能在构造器中检查依赖的存在,而且很难进行单元测试。

    @Service
    public class UserService {
        @Autowired
        private UserRepository userRepository;
    
        // ...
    }
    

以上就是 Spring 支持的三种依赖注入方式。在实际开发中,我们通常推荐使用构造器注入,因为它可以确保 bean 的不变性和必要性,而且更容易进行单元测试。

Spring 可以注入 null 和空字符串吗?

是的,Spring可以注入null值和空字符串。

对于null值的注入,可以通过在Spring配置文件中使用<null/>标签来实现。例如:

<bean id="exampleBean" class="com.example.ExampleBean">
    <property name="exampleProperty" >
        <null/>
    </property>
</bean>

在上述配置中,exampleProperty属性被设置为null。

对于空字符串的注入,可以直接在配置文件中使用空的<value/>标签或者直接将值设置为""。例如:

<bean id="exampleBean" class="com.example.ExampleBean">
    <property name="exampleProperty" value=""/>
</bean>

或者

<bean id="exampleBean" class="com.example.ExampleBean">
    <property name="exampleProperty">
        <value></value>
    </property>
</bean>

在上述两个配置中,exampleProperty属性被设置为一个空字符串。

Spring Bean 支持哪几种作用域?

Spring框架支持以下五种作用域:

  1. Singleton(单例):这是默认的作用域。在这个作用域中,Spring IoC 容器只会创建一个实例,每次请求都会返回同一个实例。这对于需要共享状态的对象非常有用。

  2. Prototype(原型):在这个作用域中,每次请求都会创建一个新的实例。这对于需要独立状态的对象非常有用。

  3. Request(请求):在这个作用域中,每个HTTP请求都会创建一个新的Bean。这个作用域仅在Web应用环境下有效。

  4. Session(会话):在这个作用域中,每个HTTP会话都会创建一个新的Bean。这个作用域也仅在Web应用环境下有效。

  5. Application(应用):在这个作用域中,Bean的生命周期与ServletContext的生命周期相同。也就是说,Bean的生命周期与整个Web应用的生命周期相同。

  6. WebSocket(WebSocket会话):在这个作用域中,每个WebSocket会话都会创建一个新的Bean。这个作用域也仅在Web应用环境下有效。

通过在@Bean注解或XML配置中指定作用域,可以控制Spring Bean的生命周期。例如,下面的代码将BookService的作用域设置为Prototype,这意味着每次注入BookService时,都会创建一个新的实例:

@Bean(scope = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public BookService bookService() {
    return new BookService();
}

由于内容太多,更多内容以链接形势给大家,点击进去就是答案了

16. 解释一下Spring Bean 的E生命周期?

17. Spring Bean 默认是单例还是多例?

18. Spring Bean 默认为单例,请说一下原因?

19. Spring Bean 如何配置为多例模式?

20. Spring Bean 是否为线程安全吗?

21. Spring Bean 如何设置为默认 Bean?

22. Spring 防止相同类型 Bean 注入异常的方法?

23. Spring 如何在 Bean 初始化时进行操作?

24. Spring 如何在 Bean 销毁时进行操作?

25. Spring 中 @Component, @Service, @Repository, @Controller 的区别是什么?

26. Spring 中的 @Bean 与 @Component 注解的区别有哪些?

27. Spring 中的 @Bean 与 @Component 注解用在同一个类上,会怎么样? 容器中Bean的数量?

28. Spring 中的 @Autowired 注解的作用?

29. Spring 中的 @Autowired 注解的用法有哪些?

30. Spring 中的 @Autowired 注解默认按什么方式装配?

31. Spring 中的 @Autowired 注入 request 是线程安全的吗?

32. Spring 中使用 @Resource,@Autowired,@lnject 的区别有哪些?

33. Spring 不推荐使用 @Autowired 字段注入的原因是什么? 应该怎么使用?

34. Spring 中的 @Required 注解的作用?

35. Spring 中的 @Qualifier 注解的作用?

36. Spring 怎么注入 Java 集合类型?

37. Spring 中的 Bean 有多个实现类,该怎么指定注入?

38. 解释一下Spring 装配?

39. Spring 自动装配的方式有哪些?

40. Spring 自动装配的局限性有哪些?

41. 解释一下Spring 循环依赖?

42. Spring 允许循环依赖吗?

43. Spring 是如何解决循环依赖的?

44. Spring 怎么禁用循环依赖?

45. Spring 需要三级缓存解决循环依赖,而不是二级缓存的原因是什么?

46. 解释一下Spring AOP ?

47. Spring AOP 的作用?

48. Spring AOP 的实现方式有哪些?

49. Spring AOP和 AspectJ AOP 的区别有哪些?

50. Spring AOP 的通知注解有哪些?

51. 说一下Spring AOP 通知注解的执行顺序?

52. Spring 支持的事务管理类型有哪些?

53. Spring 用哪种事务管理类型比较合适?

54. Spring 用什么注解开启事务?

55. 解释一下Spring 事务的实现原理?

56. Spring 事务和数据库事务的区别是?

57. Spring 支持的事务管理器有哪些?

58. Spring 中的 @Transactional 事务注解支持哪些参数?

59. 说一下Spring 事务的隔离级别有哪些?

60. 说一下Spring 事务的传播机制有哪些?

61. Spring 事务默认回滚的异常是什么?

62. Spring 事务如何指定回滚的异常?

63. Spring 事务如何指定不回滚的异常?

64. Spring 事务失效的原因是?

65. 解释一下Spring 只读事务?

66. 说一下Spring 只读事务的应用场景?

67. Spring 如何配置只读事务?

68. 解释一下Spring 超时事务?

69. Spring 如何配置超时事务?

70. 说一下Spring 超时事务的应用场景?

71. Spring 如何开启方法异步执行?

72. Spring 如何开启定时任务?

73. Spring 不建议使用默认线程池的原因是?

74. Spring 中的 Aware 接口的作用?

75. 说一下Spring 常用的 Aware 接口?

76. Spring 中的 @lmport 注解的作用?

77. Spring 中的 @Enable* 注解的作用?

78. 解释一下Spring 中的 @Enable* 注解的原理?

79. Spring 中的事件监听机制是什么?

80. Spring 可以不要 xml 配置文件吗?

81. Spring 默认支持的缓存框架是什么?

82. 说一说Spring 5.0 的新功能?

83. Spring Native 是什么框架?

84. Spring Native 和JVM 的区别是?

posted @ 2023-12-19 21:42  帅地  阅读(27)  评论(0编辑  收藏  举报