一、为了降低Java开发的复杂性,Spring采取了那4种关键策略
基于POJO的轻量级和最小侵入性编程;
通过依赖注入和面向接口实现松耦合;
基于切面和惯例进行声明式编程;
通过切面和模板减少样板式代码。
二、Spring框架的核心:
IoC容器和AOP模块。
通过IoC容器管理POJO对象以及他们之间的耦合关系;通过AOP以动态非侵入的方式增强服务。
IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。
三、Spring由哪些模块组成?
Spring 总共大约有 20 个模块, 由 1300 多个不同的文件构成。 而这些组件被
分别整合在核心容器(Core Container) 、 AOP(Aspect Oriented Programming)
和设备支持(Instrumentation) 、数据访问与集成(Data Access/Integeration) 、
Web、 消息(Messaging) 、 Test等 6模块中。 以下是 Spring 5 的模块结构
图:
spring core:提供了框架的基本组成部分,包括控制反转(Inversion of
Control,IOC)和依赖注入(Dependency Injection,DI)功能。
spring beans:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管
理对象称为Bean。
spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框
架式的对象访问方法。
spring jdbc:提供了一个JDBC的抽象层,消除了烦琐的JDBC编码和数据库厂
商特有的错误代码解析, 用于简化JDBC。
spring aop:提供了面向切面的编程实现,让你可以自定义拦截器、切点等。
spring Web:提供了针对 Web 开发的集成特性,例如文件上传,利用 servlet
listeners 进行 ioc 容器初始化和针对 Web 的 ApplicationContext。
spring test:主要为测试提供支持的,支持使用JUnit或TestNG对Spring组件进
行单元测试和集成测试。
四、Spring 框架中都用到了哪些设计模式?
1. 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
2. 单例模式:Bean默认为单例模式。
3. 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
4. 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
5. 观察者模式:
定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。
五、Spring框架中有哪些不同类型的事件
Spring 提供了以下5种标准的事件:
1. 上下文更新事件(ContextRefreshedEvent):
在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
2. 上下文开始事件(ContextStartedEvent):
当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
3. 上下文停止事件(ContextStoppedEvent):
当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
4. 上下文关闭事件(ContextClosedEvent):
当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
5. 请求处理事件(RequestHandledEvent):
在Web应用中,当一个http请求(request)结束触发该事件。如果一个bean实现了
ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。
六、Spring 的 IoC支持哪些功能
Spring 的 IoC 设计支持以下功能:
依赖注入
依赖检查
自动装配
支持集合
指定初始化方法和销毁方法
支持回调某些方法(但是需要实现 Spring 接口,略有侵入)
IoC 在 Spring 里,只需要低级容器就可以实现,2 个步骤:
1. 加载配置文件,解析成 BeanDefinition 放在 Map 里。
2. 调用 getBean 的时候,从 BeanDefinition 所属的 Map 里,拿出 Class 对象进行实例化,同时,如果有依赖关系,将递归调用 getBean 方法 —— 完成依赖注入。
七、BeanFactory 和 ApplicationContext有什么区别?
ApplicationContext是BeanFactory的子接口。
依赖关系:
BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取
bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean
之间的依赖关系。
ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具
有的功能外,还提供了更完整的框架功能:
继承MessageSource,因此支持国际化。
统一的资源文件访问方式。
提供在监听器中注册bean的事件。
同时加载多个配置文件。
载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
加载方式:
BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean
时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些
存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加
载后,直至第一次使用调用getBean方法才会抛出异常。
ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,
在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所
依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通
过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建
好了。
相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空
间。当应用程序配置Bean较多时,程序启动较慢。
创建方式:
BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方
式创建,如使用ContextLoader。
注册方式:
BeanFactory和ApplicationContext都支持BeanPostProcessor、
BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要
手动注册,而ApplicationContext则是自动注册。
BeanFactory 简单粗暴,可以理解为就是个 HashMap,Key 是 BeanName,
Value 是 Bean 实例。通常只提供注册(put),获取(get)这两个功能。我
们可以称之为 “低级容器”。
ApplicationContext 可以称之为 “高级容器”。因为他比 BeanFactory 多了
更多的功能。他继承了多个接口。因此具备了更多的功能。例如资源的获取,支
持多种消息(例如 JSP tag 的支持),对 BeanFactory 多了工具级别的支持等
待。所以你看他的名字,已经不是 BeanFactory 之类的工厂了,而是 “应用上
下文”, 代表着整个大容器的所有功能。该接口定义了一个 refresh 方法,此
方法是所有阅读 Spring 源码的人的最熟悉的方法,用于刷新整个容器,即重新
加载/刷新所有的 bean。