Spring
1. 什么是 Spring ?
Spring 是一种轻量级开发框架,皆在指提高开发人员的开发效率以及系统的可维护性。
特征:
- 核心技术:依赖注入(DI),AOP,事件(events),资源,i18n,验证,数据绑定,类型转换,SpEL
- 测试:模拟对象,TestContext框架,Spring MVC测试,WebTestClient
- 数据访问:事务,DAO 支持,JDBC,ORM,编组XML
- Web支持:Spring MVC 和 Spring WebFlux Web框架
- 集成:远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存
- 语言:Kotlin,Groovy,动态语言。
2. 列举一些重要的 Spring 模块
- Spring Core:基础,可以说 Spring 其它所有的功能都需要依赖该类库,主要提供 IOC 依赖注入功能;
- Spring Aspects:该模块为与 AspectJ 的集成提供支持;
- Spring AOP:提供了面向切面的编程实现;
- Spring JDBC:Java数据库连接;
- Spring JMS:Java 消息服务;
- Spring ORM:用于支持 Hibernate 等 ORM 工具;
- Spring Web:为创建Web 应用程序提供支持;
- Spring test:提供了对 Junit 和 TestNG 测试的支持
3. @RestController 和 @Controller
@RestController注解,相当于 @Controller + @ResponseBody 两个注解的结合,返回 json 数据不需要在方法前面加 @ResponeBody 注解了,但使用 @RestController 这个注解,就不能返回 jsp,html 页面了。视图解析器无法解析 jsp ,html 页面
- 如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,配置的视图解析器InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。
例如:本来应该到success.jsp页面的,则其显示success.
- 如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
- 如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。
4. Spring IOC 和 AOP
暂时略
5. Spring bean
Spring bean 的作用域有哪些:
- singleton:唯一 bean 实例,Spring 中的 bean 默认都是单列的;
- prototype:每次请求都会创建一个新的 bean 实例;
- request:每一次 HTTP 都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效;
- session:每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在 当前 HTTP session 内有效;
- global-session:全局session作用域,仅仅在protlet的web 应用中才有意义。Spring 5 已经没有了
@Component 和 @Bean 区别:
- 作用对象不同:
@Component
注解作用于类,而 @Bean
注解作用于 方法; @Component
通常是通过类路径扫描来自动侦测以及自动装配到Soring容器中(我们可以使用 @ComponentScan
注解定义要扫描的路径从中标识了需要装配的类自动装配到 Spring 的 Bean容器中)。@Bean
注解通常是我们在标有该注解的方法中定义产生这个 bean, @Bean
告诉了Spring 这是某个类的实例,当我们需要它的时候还给我们。@Bean
注解比 Component
注解的自定义更强,而且很多地方我们只能通过 @Bean
注解来注册 bean
。比如当我们引用第三方库中的类需要装配到 Spring
容器时,则只能通过 @Bean
来实现。
将一个类声明为 Spring 的 bean 的注解有哪些?
我们一般使用 @Autowired 注解自动装配 bean,要想把类表示成可用于 @Autowired 注解自动装配的 bean 的类,采用以下注解可实现:
@Component
:通用的注解,可标注任意类为 Spring
组件。如果一个 bean
不知道属于哪个层,可以使用 @Component
注解标注。@Repository
:对应持久层即 Dao
层,主要用于数据库相关操作;@Service
:对应服务层,主要涉及一些复杂的逻辑,需要用到Dao
层;@Controller
:对应 Spring MVC
控制层,主要用于接收用户请求并调用 Service
层返回数据给前端。
Spring 中 bean 声明周期
推荐阅读:@Chandler Qian版 Spring Bean 的声明周期
【Spring】Bean的生命周期
Bean
容器找到配置文件中 Spring Bean
的定义;Bean
容器利用 Java Reflection API
创建一个 Bean
的实例;- 如果涉及到一些属性值,利用
set()
方法设置一些属性值; - 如果
Bean
实现了BeanNameAware
接口,调用 setBeanName()
方法,传入Bean
的名字; - 如果
Bean
实现了 BeanClassLoaderAware
接口,调用setBeanClassLoader()
方法,传入ClassLoader
对象的实例。 - 与上面的类似,如果实现了其他
*.Aware
接口,就调用相应的方法。 - 如果有和加载这个
Bean
的Spring
容器相关的BeanPostProcessor
对象,执行postProcessBeforeInitialization()
方法 - 如果
Bean
实现了InitializingBean
接口,执行afterPropertiesSet()
方法。 - 如果
Bean
在配置文件中的定义包含init-method
属性,执行指定的方法。 - 如果有和加载这个
Bean
的Spring
容器相关的BeanPostProcessor
对象,执行postProcessAfterInitialization()
方法 - 当要销毁
Bean
的时候,如果Bean
实现了DisposableBean
接口,执行destroy()
方法。 - 当要销毁
Bean
的时候,如果Bean
在配置文件中的定义包含destroy-method
属性,执行指定的方法。
Spring MVC
暂略
Spring 框架中用到了哪些设计模式?
直接阅读这篇文章吧!面试官:“谈谈Spring中都用到了那些设计模式?”
Spring 事务
Spring 管理事务的方式有几种?
- 编程式事务,在代码中硬编码。(不推荐使用)
- 声明式事务,在配置文件中配置(推荐使用)
声明式事务又分为两种:
- 基于 XML 的声明式事务
- 基于注解的声明式事务
Spring 事务中的隔离级别分为几种?
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
- TransactionDefinition.ISOLATION_DEFAULT:使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别
- TransactionDefinition.ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
- TransactionDefinition.ISOLATION_READ_COMMITTED:**允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生**
- TransactionDefinition.ISOLATION_REPEATABLE_READ:**对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。**
- **TransactionDefinition.ISOLATION_SERIALIZABLE:**最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
Spring 事务中 有哪几种事务传播行为?
支持当前事务的情况?
- TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
- TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
- TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
不支持当前事务的情况:
- TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
其它 情况:
- TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
JPI
暂略