1.什么是spring
spring是一个开源框架,它是为了解决企业应用开发复杂性而创建的。使用基本的JavaBean代替复杂的EJB完成的事情。
2.spring框架有哪些优点
- 使用spring的IOC容器,将对象之间的关系交给Spring,降低组件之间的耦合。
- 对主流框架有很好的集成,如JPA、mybatis等
- AOP编程的支持,通过spring AOP,方便进行面向切面编程,许多不容易用传统面向对象实现的功能可以通过AOP轻松应付。
- 声明式事务的支持,将业务逻辑代码与事务管理分离。
- 方便程序测试
3.spring的基本模块
模块名称 | 描述 |
---|---|
spring core | Spring Core模块是Spring的核心容器,它实现了IOC模式,提供了Spring框架的基础功能。此模块中包含的BeanFactory类是Spring的核心类,负责JavaBean的配置与管理。 |
spring context | Spring Context模块继承BeanFactory(或者说Spring核心)类,并且添加了事件处理、国际化、资源装载、透明装载、以及数据校验等功能。 |
spring DAO | DAO模块提供了JDBC的抽象层,简化了数据库厂商的异常错误(不再从SQLException继承大批代码),大幅度减少代码的编写,并且提供了对声明式事务和编程式事务的支持。 |
spring ORM | 对Hibernate提供了完美的整合功能,同时也支持其他ORM工具。注意这里Spring是提供各类的接口(support),目前比较流行的下层数据库封闭映射框架,如 ibatis, Hibernate等。 |
spring AOP | AOP从功能的角度来讲,可能看作OOP编程方式的一种补充,提供了一种不同的代码或者系统组织方式。 |
spring web | 此模块建立在Spring Context 基础之上,它提供了Servlet监听器的Context 和 Web应用的上下文。 |
spring web mvc | Spring WebMVC模块建立在Spring核心功能之上,这使它能拥有Spring框架的所有特性,能够适应多种多视图、模板技术、国际化和验证服务,实现控制逻辑和业务逻辑的清晰分离。 |
4.BeanFactory – BeanFactory 实现举例
Bean工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从正真的应用代码中分离。最常用的BeanFactory 实现是XmlBeanFactory 类。
5.什么是Spring IOC 容器
Spring IOC容器负责创建对象、管理对象。通过依赖注入(DI),装配对象,并且管理这些对象的整个生命周期。
IOC的优点:实现组件之间的解耦,提高程序的灵活性和可维护性。
6.Bean Factory和Application Contexts有什么区别
BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。
ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。ApplicationContext包还提供了以下的功能:
• MessageSource, 提供国际化的消息访问
• 资源访问,如URL和文件
• 事件传播
• 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
7.Spring 框架中都用到了哪些设计模式
模式 | 描述 |
---|---|
工厂模式 | BeanFactory和 ApplicationContext创建都是用到工厂模式 |
模板模式 | RestTemplate, JmsTemplate, JpaTemplate |
代理模式 | 在AOP实现中用到了JDK的动态代理 |
单例模式 | 这个比如在创建bean的时候 |
迭代器模式 | Iterable接口和Iterator接口 |
8.什么是控制反转?什么是依赖注入?
控制反转(IoC/Inverse Of Control): 调用者不再创建被调用者的实例,由spring框架实现(容器创建,其实就是XML中配置)所以称为控制反转。
依赖注入(DI/Dependence injection) : 容器创建好实例后再注入调用者称为依赖注入。
9.依赖注入的方式
(1)构造方法注入
在spring的配置文件中注册UserService,将UserDaoJdbc通过constructor-arg标签注入到UserService的某个有参数的构造方法
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>
如果只有一个有参数的构造方法并且参数类型与注入的bean的类型匹配,那就会注入到该构造方法中。
public class UserService implements IUserService {
private IUserDao userDao;
public UserService(IUserDao userDao) {
this.userDao = userDao;
}
public void loginUser() {
userDao.loginUser();
}
}
(2)setter注入
配置如下
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<!-- 写法一 -->
<!-- <property name="UserDao" ref="userDaoMyBatis"></property> -->
<!-- 写法二 -->
<property name="userDao" ref="userDaoMyBatis"></property>
</bean>
<!-- 注册mybatis实现的dao -->
<bean id="userDaoMyBatis" class="com.lyu.spring.dao.impl.UserDaoMyBatis"></bean>
注入如下:
public class UserService implements IUserService {
private IUserDao userDao1;
public void setUserDao(IUserDao userDao1) {
this.userDao1 = userDao1;
}
public void loginUser() {
userDao1.loginUser();
}
}
还有一点需要注意:如果通过set方法注入属性,那么spring会通过默认的空参构造方法来实例化对象,所以如果在类中写了一个带有参数的构造方法,一定要把空参数的构造方法写上,否则spring没有办法实例化对象,导致报错。
10.哪种依赖注入方式你建议使用
最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖。
11.什么是Spring beans
Spring Beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化、装配和管理。
12.如何给Spring 容器提供配置元数据(spring有几种配置方式)
(1)基于XML的配置
<beans>
<bean name="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
</beans>
使用Spring命名空间的所支持的一系列的XML标签来实现的。Spring有以下主要的命名空间:context、beans、jdbc、tx、aop、mvc和aso。
(2)基于注解的配置
注解装配在Spring中是默认关闭的。所以需要在Spring文件中配置一下才能使用基于注解的装配模式
<beans>
<context:annotation-config/>
</beans>
@Scope(“prototype”)
@Lazy(true)
@Component(“loginUserDao”)
public class LoginUserDao {
// 用于设置初始化方法
@PostConstruct
public void myInit() {
}
// 用于设置销毁方法
@PreDestroy
public void myDestroy() {
}
}
在Bean实现类中通过一些Annotation来标注Bean类:
·@Component:标注一个普通的Spring Bean类(可以指定Bean名称,未指定时默认为小写字母开头的类名)
·@Controller:标注一个控制器类
·@Service:标注一个业务逻辑类
·@Repository:标注一个DAO类
(3)基于java的配置
@Configuration
public class AppConfig
{
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
Spring对Java配置的支持是由@Configuration注解和@Bean注解来实现的。由@Bean注解的方法将会实例化、配置和初始化一个新对象,这个对象将由Spring的IoC容器来管理。 被@Configuration所注解的类则表示这个类的主要目的是作为bean定义的资源。
在标注了@Configuration的java类中,通过在类方法标注@Bean定义一个Bean。方法必须提供Bean的实例化逻辑。通过@Bean的name属性可以定义Bean的名称,未指定时默认名称为方法名。在方法处通过@Autowired使方法入参绑定Bean,然后在方法中通过代码进行注入;
优缺点对比:
基于XML的配置 | 基于注解的配置 | 基于java的配置 | |
---|---|---|---|
优点 | 1)XML配置方式进一步降低了耦合,使得应用更加容易扩展,即使对配置文件进一步修改也不需要工程进行修改和重新编译。2)在处理大的业务量的时候,用XML配置应该更加好一些。 | 1)在class文件中,降低维护成本。2)不需要第三方解析工具,利用java反射机制。3)编辑期就可以检验正确性,提高开发效率。 | 1)在class文件中,降低维护成本。2)不需要第三方解析工具,利用java反射机制。3)编辑期就可以检验正确性,提高开发效率。 |
缺点 | 1)配置文件读取和解析需要花费一定的时间,配置文件过多的时候难以管理。 | 1)如果需要对annotation进行修改,那么要重新编译整个工程。2)业务类之间的关系不如XML配置那样容易把握。 | 1)配置代码过多时,直接影响代码质量,对于代码的简洁度有影响。2)业务类之间的关系不如XML配置那样容易把握。3)如果需要修改配置,则要重新编译整个工程。 |
13.怎样定义类的作用域
通过bean 定义中的scope属性来定义。例如:当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。
14.Spring Bean的作用域之间有什么区别
作用域 | 描述 |
---|---|
单例(singleton) | (默认)每一个Spring IoC容器都拥有唯一的一个实例对象 |
原型(prototype) | 为每一个bean请求提供一个实例 |
请求(request) | 每一个HTTP请求都有自己的Bean实例,请求完成以后,bean会失效并被垃圾回收器回收 |
会话(session) | 每个session中有一个bean的实例,在session过期后,bean会随之失效。 |
全局会话(global session) | 限定一个Bean的作用域为全局HTTPSession的生命周期。 |
应用(application) | 限定一个Bean的作用域为ServletContext的生命周期 |
15.Spring框架中的单例Beans是线程安全的么
Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。
16.哪些是重要的bean生命周期方法? 你能重载它们吗?
有两个重要的bean生命周期方法:
第一个是setup,它是在容器加载bean的时候被调用。
第二个方法是 teardown 它是在容器卸载类的时候被调用。
The bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。
17.什么是spring的内部bean
当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean。内部bean通常是匿名的,它们的Scope一般是prototype。
18.什么是Bean自动装配
Spring 容器能够自动装配相互合作的bean,这意味着容器不需要<constructor-arg>和<property>配置,能通过Bean工厂自动处理bean之间的协作。
19.不同方式的自动装配
装配方式 | 描述 |
---|---|
no | 默认的方式是不进行自动装配,通过显式设置ref 属性来进行装配。 |
byName | 通过参数名 自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。 |
byType | 通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。 |
constructor | 这个方式类似于byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。 |
autodetect | 首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。 |
20.自动装配的局限性
- 重写: 你仍需用 <constructor-arg>和 <property> 配置来定义依赖,意味着总要重写自动装配。
- 基本数据类型:你不能自动装配简单的属性,如基本数据类型,String字符串,和类。
- 模糊特性:自动装配不如显式装配精确,如果有可能,建议使用显式装配。
21.什么是基于Java的Spring注解配置? 给一些注解的例子.
允许在少量的Java注解的帮助下,进行大部分Spring配置而非通过XML文件。
例1:@Configuration注解,用来标记类可以当做一个bean的定义,被Spring IOC容器使用。
例2:@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
22.在Spring框架中如何更有效地使用JDBC
- 使用JDBC框架,资源管理和错误处理的都会容易很多,开发者只需写statements 和 queries从数据存取数据;
- JDBC可以在Spring提供的模板类的帮助下更有效地被使用,这个模板叫JdbcTemplate
23.使用Spring通过什么方式访问Hibernate
- 控制反转 Hibernate Template和 Callback。
- 继承 HibernateDAOSupport提供一个AOP 拦截器。
24.Spring支持的ORM
- Hibernate
- iBatis
- JPA (Java Persistence API)
25.Spring支持的事务管理类型
- 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
- 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。
26.Spring框架的事务管理有哪些优点?
- 它为不同的事务API (如 JTA,JDBC,Hibernate,JPA 和JDO),提供一个不变的编程模式。
- 它为编程式事务管理提供了一套简单的API而不是一些复杂的事务API。
- 它支持声明式事务管理。
- 它和Spring各种数据访问抽象层很好得集成。
27.什么是AOP
面向切面的编程是一种编程技术,使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。 避免了在业务逻辑的代码中混入很多的系统相关的逻辑 ——比如权限管理,事物管理,日志记录等等。
28.AOP 术语
通知:
- 定义:切面也需要完成工作。在 AOP 术语中,切面的工作被称为通知。
- 工作内容:通知定义了切面是什么以及何时使用。除了描述切面要完成的工作,通知还解决何时执行这个工作。
- 5 种通知类型
通知类型 | 描述 |
---|---|
Before | 在方法调用之前调用通知 |
After | 在方法完成之后调用通知,无论方法执行成功与否 |
After-returning | 在方法执行成功之后调用通知 |
After-throwing | 在方法抛出异常后进行通知 |
Around | 通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为 |
连接点:
- 定义:连接点是一个应用执行过程中能够插入一个切面的点。
- 连接点可以是调用方法时、抛出异常时、甚至修改字段时、
- 切面代码可以利用这些点插入到应用的正规流程中
- 程序执行过程中能够应用通知的所有点。
切点:
- 定义:如果通知定义了“什么”和“何时”。那么切点就定义了“何处”。切点会匹配通知所要织入的一个或者多个连接点。
- 通常使用明确的类或者方法来指定这些切点。
- 作用:定义通知被应用的位置(在哪些连接点)
切面:
- 定义:切面是通知和切点的集合,通知和切点共同定义了切面的全部功能——它是什么,在何时何处完成其功能。
引入:
- 引入允许我们向现有的类中添加方法或属性
织入:
- 织入是将切面应用到目标对象来创建的代理对象过程。
- 切面在指定的连接点被织入到目标对象中,在目标对象的生命周期中有多个点可以织入
29.什么是Spring的MVC框架
Spring可以很便捷地和其他MVC框架集成,如Struts、SpringMVC。
Spring 的MVC框架用控制反转把业务对象和控制逻辑清晰地隔离。它也允许以声明的方式把请求参数和业务对象绑定。
30.DispatcherServlet
Spring的MVC框架是围绕DispatcherServlet来设计的,它用来处理所有的HTTP请求和响应。
31.什么是SpringBoot
springboot提供了一种新的编程范式,可在最小的阻力下进行spring应用程序开发。专注于应用程序的功能,不需要再配置上花费太多时间。
32.Spring Boot、Spring MVC 和 Spring 有什么区别
SpringFrame:SpringFramework 最重要的特征是依赖注入和控制反转。所有 Spring模块不是依赖注入就是 IOC 控制反转。 当我们恰当的使用 DI 或者是 IOC 的时候,我们可以开发松耦合应用。松耦合应用的单元测试可以很容易的进行。
SpringMVC:Spring MVC 提供了一种分离式的方法来开发 Web 应用。通过运用像 DispatcherServelet,MoudlAndView 和 ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。
SpringBoot:Spring 和 SpringMVC 的问题在于需要配置大量的参数。 Spring Boot 通过一个自动配置和启动的项来目解决这个问题。为了更快的构建产品就绪应用程序,Spring Boot 提供了一些非功能性特征。
33.Spring Boot有什么特点
- 自动配置:提高开发效率
- 起步依赖:根据依赖传递关系,把其他需要的依赖也加进来
- 内嵌容器:通过配置选择不同的容器,通过java -jar启动应用程序
- yml配置文件:解决重复的链式配置
34.什么是自动配置(自动配置的原理)
- spring boot程序在启动时扫描项目所依赖的jar包(添加SpringBootApplication注解或者EnableAutoConfiguratoin注解)
- 寻找包含spring.factories配置文件,该文件声明了哪些需要自动配置。
- 根据条件进行自动配置,并将bean注入到spring上下文。
35.什么是 Spring Boot Stater
起步依赖,根据依赖传递关系,把其他需要的依赖加进来。
例如,如果你想使用Spring和JPA进行数据库访问,只需要在你的项目中引入spring-boot-starter-data-jpa
依赖就可以。
36.Spring Boot 还提供了其它的哪些 Starter
starter名称 | 描述 |
---|---|
spring-boot-starter-web | Web 和 RESTful 应用程序 |
spring-boot-starter-test | 单元测试和集成测试 |
spring-boot-starter-data-jpa | 引入Spring Boot JPA,访问数据库 |
spring-boot-starter-data-redis | Redis数据库支持 |
37.创建一个 Spring Boot Project 的最简单的方法是什么
Spring initializer[i'niʃəlaizə]是启动 Spring Boot Projects 的一个很好的工具。
38.如何使用 SpringBoot 自动重装的应用程序
添加spring-boot-devtools依赖,重启应用程序即可。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
40.我们能否在 spring-boot-starter-web 中用 jetty 代替 tomcat
在 spring-boot-starter-web 移除现有的依赖项,并把下面这些添加进去。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
41.如何使用 Spring Boot 部署到不同的服务器
- 在一个项目中生成一个 war 文件。
- 将它部署到你最喜欢的服务器(websphere 或者 Weblogic 或者 Tomcat ...)
42.JPA 和 Hibernate 有哪些区别
- JPA 是一个规范或者接口
- Hibernate 是 JPA 的一个实现
43.什么是嵌入式服务器?我们为什么要使用嵌入式服务器呢?
传统的web项目都是需要部署到服务容器上,例如tomcat、weblogic,然后启动容器运行应用程序。
而springboot应用程序只需要运行**application中的main方法,原因是springboot封装了web容器,启动时会根据配置启动相应的容器,默认是tomcat。
SpringBoot这种设计在微服务架构下有明显的优点(为什么要使用嵌入式服务器):
- 可以创建独立、自启动的应用容器
- 不需要构建War包并发布到容器中,构建和维护War包、容器的配置和管理也是需要成本和精力的
- 通过Maven的定制化标签,可以快速创建SpringBoot的应用程序
- 可以最大化地自动化配置Spring,而不需要人工配置各项参数
- 提供了产品化特点,例如:性能分析、健康检查和外部化配置
- 全程没有XML配置,也不需要代码生成
44.什么是微服务
微服务是一种架构风格,一个大型复杂的应用程序由一个或者多个微服务组成,各个微服务独立部署,每个服务只关注自己的业务。
45.微服务的特点
- 独立部署,扩展性强.
- 多个开发团队可以并行开发.
- 一台服务宕机,不会影响其他服务.
- 技术选型灵活.
46.Spring Cloud的核心功能
功能名称 | 描述 |
---|---|
分布式/版本化配置 | Spring Cloud Config为分布式系统中的外部化配置提供支持。 |
服务注册与发现 | Spring Cloud Eureka服务治理,是微服务中最为核心和基础的模块,主要用来实现各个微服务实例的自动化注册和发现。 |
路由 | Spring Cloud Zuul是提供动态路由、监控、安全等服务的框架。 |
服务与服务之间的调用 | 1.Spring Cloud Ribbon是一个基于HTTP的客户端负载均衡工具;2.Spring Cloud Feign是一种声明式、模块化的HTTP客户端。 |
断路器 | Spring Cloud Hystrix,由于网络问题或者程序问题,服务并不是100%可用,如果服务出现问题,调用服务就会出现阻塞,这个时候如果出现大量请求,容器线程资源就会被耗尽,导致服务瘫痪。 |
分布式消息传递 | MQ |
47.Spring Cloud如何实现服务的注册与发现
服务在发布时,指定对应的服务名将服务注册到注册中心。
这一过程是springcloud自动实现 只需要在main方法添加@EnableDisscoveryClient 同一个服务修改端口就可以启动多个实例
调用方法:传递服务名称通过注册中心获取所有的可用实例 通过负载均衡策略调用(ribbon和feign)对应的服务.
48.SpringCloud断路器的作用
当一个服务调用另一个服务由于网络原因或者自身原因出现问题时 调用者就会等待被调用者的响应 当更多的服务请求到这些资源时导致更多的请求等待 这样就会发生连锁效应(雪崩效应) 断路器就是解决这一问题。
断路器有三种状态:
状态名称 | 描述 |
---|---|
完全打开 | 一定时间内,达到一定的次数无法调用 并且多次检测没有恢复的迹象 断路器完全打开,那么下次请求就不会请求到该服务 |
半开 | 短时间内有恢复迹象,断路器会将部分请求发给该服务。当能正常调用时,断路器关闭 |
关闭 | 当服务一直处于正常状态,能正常调用,断路器关闭 |
49.常用的负载均衡策略
- 简单轮询负载均衡 2. 加权响应时间负载均衡 3. 区域感知轮询负载均衡 4. 随机负载均衡
50.Spring Cloud Config
- SpringCloudConfig就是我们通常意义上的分布式配置中心,把应用原本放在本地文件的配置抽取出来放在中心服务器,从而能够提供更好的管理、 发布能力。
- SpringCloudConfig分为服务端和客户端,服务端负责将git(svn)中存储的配置文件发布成REST接口,客户端可以从服务端REST接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置, 它需要每个客户端通过POST方法触发各自的/refresh,SpringCloudBus就通过一个轻量级消息代理连接分布式系统的节点。
- 可以用于广播状态更改(如配置更改)或其他管理指令。
- SpringCloudBus提供了通过POST方法访问的endpoint/bus/refresh,这个接口通常由git的钩子功能调用,用以通知各个SpringCloudConfig的客户端去服务端更新配置。