一、Spring面试题

1、Spring 在SSM框架中起什么作用?

  • Spring:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

  • 作用:Bean工厂,用来管理Bean的生命周期和框架集成,Spring顶层容器为BeanFactory。

  • 两大核心:①、IoC/DI(控制反转/依赖注入) :Ioc的作用是解决对象之间的依赖问题,把所有Bean的依赖关系通过配置文件或注解关联起来,降低了耦合度。②、AOP:面向切面编程


2、为什么使用Spring?

①方便解耦,简化开发(IoC:通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。)

②AOP编程的支持(通过Spring提供的AOP功能,方便进行面向切面的编程)

③声明式事务的支持(可以从单调烦闷的事务管理代码中解脱出来,)

④方便程序的测试(Spring对Junit4支持,可以通过注解方便的测试Spring程序。)

⑤方便集成各种优秀框架(Spring不排斥各种优秀的开源框架如Struts,Hibernate)


3、IoC,AOP的实现原理?

  • IoC:反射机制+工厂模式,通过反射机制生成对象注入

  • AOP:动态代理,使用JDK的动态代理(接口代理)或者CGlib(扩展代理类)实现。

AOP(Aspect-Oriented Programming,面向切面编程):可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。AOP技术它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,比如事务、安全和日志等问题,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

AOP的核心思想就是将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。


4、Spring的配置文件中的内容?

  • 开启事务注解驱动

  • 事务管理器

  • 开启注解功能,并配置扫描包

  • 配置数据库

  • 配置SQL会话工厂,别名,映射文件

  • 不用编写Dao层的实现类


5、Spring下的注解?

  • 注册:@Controller @Service @Component

  • 注入:@Autowired @Resource

  • 请求地址:@RequestMapping

  • 返回具体数据类型而非跳转:@ResponseBody

  • @Configuration注解:@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

  • @Bean注解:用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。用@Bean可以把第三方库中的类实例交给spring管理。

    参考链接:@bean和@Configuration注解


6、Spring DI 的三种方式?

构造器注入:通过构造方法初始化

setter方法注入:通过setter方法初始化

注解注入


7、Spring主要使用了什么模式?

  • 工厂模式:每个Bean的创建通过方法

  • 单例模式:默认的每个Bean的作用域都是单例

  • 代理模式:关于Aop的实现通过代理模式


8、Spring的事务?

  • 编程式事务管理:编程方式管理事务,极大灵活性,难维护。

  • 声明式事务管理:可以将业务代码和事务管理分离,用注解和xml配置来管理事务。


9、spring容器创建对象的时机?

第一种:默认情况下,启动 spring 容器便创建对象(遇到bean便创建对象)

第二种:在spring的配置文件bean中有一个属性 lazy-init=“default/true/false”

    ①、如果lazy-init为"default/false"在启动spring容器时创建对象(默认情况)

     ②、如果lazy-init为"true",在context.getBean时才会创建对象


10、Spring重要模块组成

Spring框架由七个定义明确的模块组成:


如果作为一个整体,这些模块为你提供了开发企业应用所需的一切。但你不必将应用完全基于Spring框架。你可以自由地挑选适合你的应用的模块而忽略其余的模块。就像你所看到的,所有的Spring模块都是在核心容器之上构建的。容器定义了Bean是如何创建、配置和管理的——更多的Spring细节。当你配置你的应用时,你会潜在地使用这些类。但是作为一名开发者,你最可能对影响容器所提供的服务的其它模块感兴趣。这些模块将会为你提供用于构建应用服务的框架,例如AOP和持久


11、Spring的容器中Bean生命周期

Spring Bean的生命周期只有这四个阶段

  • 实例化 Instantiation
  • 属性赋值 Populate
  • 初始化 Initialization
  • 销毁 Destruction

对象创建

1、从xml配置的Bean,@Bean注解,或者Java代码BeanDefinitionBuilder中读取Bean的定义,实例化Bean对象;

2、设置Bean的属性;

3、注入Aware的依赖(BeanNameAware,BeanFactoryAware,ApplicationContextAware);

4、执行通用的方法前置处理,方法: BeanPostProcessor.postProcessorBeforeInitialization()

5、执行 InitalizingBean.afterPropertiesSet() 方法

6、执行Bean自定义的初始化方法init,或者 @PostConstruct 标注的方法;

7、执行方法BeanPostProcessor.postProcessorAfterInitialization()

8、创建对象完毕;

对象销毁

9、执行 DisposableBean.destory() 方法;

10、执行自定义的destory方法或者 @PreDestory 标注的方法;

11、销毁对象完毕


12、Bean的作用域

在Spring中,bean作用域用于确定哪种类型的bean实例应该从Spring容器中返回给调用者。

<!-- A bean definition of applicationContext.xml-->
<bean id="..." class="..." scope="singleton">

目前Spring Bean的作用域或者说范围主要有五种。

注意: 使用 prototype 作用域需要慎重的思考,因为频繁创建和销毁 bean 会带来很大的性能开销。


二、SpringMVC面试题

13、SpringMVC 的Controller是不是单例模式,如果是,有什么问题,怎么解决?

  • 答案:SpringMVC的控制器默认为单例模式,在多线程访问时有线程安全问题

  • 解决方法:不要用同步,在控制器里面不能写字段

   a、不要在controller中定义成员变量

   b、万一必须要定义一个非静态成员变量时候,则在Controller类上添加注解@Scope("prototype"),将其设置为多例模式式。

   c、 在Controller中使用ThreadLocal变量

   参考链接:  Spring 的 Controller 是单例还是多例?怎么保证并发的安全


14、Spring MVC的常用注解

  • @Controller :用于标记在一个类上,该注解表明该类扮演SpringMVC控制器的角色

  • @RequestMapping:是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径

  • @PathVariable:用于将请求Restful URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数

@RequestMapping(value="/product/{productId}",method = RequestMethod.GET)

public String getProduct(@PathVariable(“productId”) String productId)
  • @Responsebody :注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般用来返回json数据。 

在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。例如,ajax异步获取 json 数据,加上              @Responsebody 注解后,就会直接返回 json 数据。

  • @RequestParam: 在SpringMVC后台控制层获取参数的方式主要有两种,一种是request.getParameter(“name”),另外一种是用注解@RequestParam直接获取。这里主要讲这个注解 。 spring会自动根据参数名字封装进入,我们可以直接拿这个参数名来用


15、前台多个参数,这些参数都是一个对象,快速得到对象?

直接在方法中声明这个对象,SpringMVC就自动把属性赋值到这个对象里面


16、SpringMVC中函数的返回值?

String,ModelAndView,List,Set 等


17、SpringMVC中的转发和重定向?

forward(转发):

forward是服务器内部的跳转,服务器直接访问目标地址的 url网址,把里面的东西读取出来,但是客户端并不知道,因此用forward的话,客户端浏览器的网址是不会发生变化的。

关于request: 由于在整个定向的过程中用的是同一个request,因此forward会将request的信息带到被重定向的jsp或者servlet中使用。

redirect(重定向):

redirect是客户端的重定向,是完全的跳转。即服务器返回的一个url给客户端浏览器,然后客户端浏览器会重新发送一次请求,到新的url里面,因此浏览器中显示的url网址会发生变化。

因为这种方式比forward多了一次网络请求,因此效率会低于forward。

1)在SpringMVC中仍然可以使用传统方式实现转发和重定向

转发:request.getRequestDispatcher(" ").forward(request,response);

重定向:response.sendRedirect(" ");

2)在SpringMVC中也提供了快捷方式实现转发和重定向,当@RequestMapping修饰的方法返回值为String

  • 转发:return "forward:hello"

  • 重定向 :return "redirect:hello.jsp"


18、SpringMVC的工作流程图和工作原理?

SpringMVC在项目中拦截用户请求,它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责,将用户请求通过HandlerMapping去匹配Controller,Controller就是具体对应请求所执行的操作,最终把Model层执行结果返回给用户。SpringMVC相当于SSH框架中struts。

工作原理:

  • 客户端发送请求,携带url地址;

  • 前端控制器Dispatcher Servlet接收到请求,调用处理器映射Handler Mapping找到对应的处理器,生成并返回handler对象;

  • 前端控制器Dispatcher Servlet调用处理器适配器Handler Adapter;

  • Handler Adapter经过适配,调用相应的适配器执行handler对象斌返回结果给Handler Adapter,再返回给前端控制器Dispatcher Servlet,结果包括数据结构和视图对象;

  • 前端控制器Dispatcher Servlet调用视图解析器View Resolver将携带的数据结构和视图对象进行解析,解析完成后响应给Dispatcher Servlet;

  • 核心控制器将结果返回给客户端。


19、Struts2 和 SpringMVC的区别?

(1)、springmvc入口是一个servlet前端控制器( DispatcherServlet ),struts2入口是一个filter过滤器(StrutsPrepareAndExecuteFilter).

(2)、struts2通过在action类中定义成员变量接收参数,(属性驱动和模型驱动),它只能使用多例模式管理action.

        springmvc通过在coontroller方法中定义形参接收参数,springmvc可以使用单例模式管理controller.

(3)、springmvc是基于方法开发的,注解开发中使用requestMapping将url和方法进行 映射,如果根据url找到controller类的方法生成一个handler处理器对象(只包括一个method).

        struts2是基于类开发的,每个请求过来创建一个action实例,实例对象中有若干个方法.

        开发中建议使用springmvc,springmvc方法更类似service业务方法.

(4)、struts2采用值栈存储请求和相应的数据,通过OGNL存取数据;springmvc通过参数绑定期将request请求内容解析,并给方法形参赋值.

(5)、struts2和springmvc的速度是相当的,由于struts2的漏洞较多,更多企业使用springmvc

(6)、SpringMVC验证支持JSR303,处理起来相对更加灵活方便,而Struts2验证比较繁琐,感觉太烦乱。

(7)、设计思想上,Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。

(8)、拦截器实现机制上,Struts2有以自己的interceptor机制,SpringMVC用的是独立的AOP方式,这样导致Struts2的配置文件量还是比SpringMVC大。


20、拦截器与过滤器的区别 :

  • 拦截器是基于java的反射机制的,而过滤器是基于函数回调。

  • 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

  • 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

  • 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

  • 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次


三、Mybatis面试题

21、Ibatis和Mybatis?

  • Ibatis:2010年,apache的Ibatis框架停止更新,并移交给了google团队,同时更名为MyBatis。从2010年后Ibatis在没更新过,彻底变成了一个孤儿框架。一个没人维护的框架注定被mybatis拍在沙滩上。

  • Mybatis:Ibatis的升级版本。

Mybatis的优点:

把Sql语句从Java中独立出来。

封装了底层的JDBC,API的调用,并且能够将结果集自动转换成JavaBean对象,简化了Java数据库编程的重复工作。

自己编写Sql语句,更加的灵活。

入参无需用对象封装(或者map封装),使用@Param注解


22、什么是Mybatis的接口绑定,有什么好处?

Mybatis实现了DAO接口与xml映射文件的绑定,自动为我们生成接口的具体实现,使用起来变得更加省事和方便。


23、什么情况用注解,什么情况用xml绑定?

  • 注解使用情况:Sql语句简单时

  • xml绑定使用情况:xml绑定 (@RequestMap用来绑定xml文件)


24、Mybatis在核心处理类叫什么?

SqlSession


25、Mybatis数据库字段名和返回实体Bean对象不一致,如何处理?

①如果数据库中的字段名与对象只是简单的不一致的话,比如名字是一样的,只是分隔方式不一样,在数据库中使用了下划线分隔,而在对象中使用了驼峰分隔,如果都是这样子的话倒不是特别麻烦,只需要在mybatis的配置文件中开启驼峰转换即可。

<setting name="mapUnderscoreToCamelCase" value="true"/>

②还有一种情况就是绝大部分情况下都是可以适配得上的,但是只有几列适配不上,这个时候定义单独的ResultMap感觉有点不值当(事实上,从可维护性上来考虑定义ResultMap绝对是首选),所以我们就在查询数据的时候在SQL语句中使用别名来使数据库列名能够适配得上对象的属性名。

<select id="loadById" parameterType="string" resultType="user">
    SELECT id, username AS name, passwd FROM t_user WHERE id=#{id}
</select>

③自定义ResultMap,映射键值对即可

实在是不一致得比较离谱,基本上大部分的数据库字段和对象的名字都是不对应的,这种情况下定义一个ResultMap来解决这个问题绝对是上策。

<select id="loadById" parameterType="string" resultMap="userResultMap">    SELECT * FROM t_user WHERE id=#{id}</select>

然后在resultMap标签中配置不同字段的映射:

<resultMap id="userMap" type="org11001100.mybatis.domain.User" autoMapping="true">    <id column="id" property="id"/>    <result column="username" property="name"/></resultMap>

resultMap标签有个属性叫做autoMapping,当指定为true的时候表示没有手动使用id或者result标签指定映射的属性就自动映射,这样将这个属性置为true,就可以只指定表字段名称与对象属性名不匹配的字段,大大减少了工作量。


26、Mybatis中的#{}跟${}有什么区别

#{}方式能够很大程度防止sql注入。${} 方 式 无 法 防 止 sql 注 入

${}:简单字符串替换,把${}直接替换成变量的值,不做任何转换,这种是取值以后再去编译SQL语句。

#{}:预编译处理,sql中的#{}替换成?,补全预编译语句,有效的防止Sql语句注入,这种取值是编译好SQL语句再取值。

总结:一般能用#{}就别用${},使用#{}格式的语法在mybatis中使用Preparement语句来安全的设置值以防止sql注入,不过有时你只是想直接在 SQL 语句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用:ORDER BY ${columnName},此时MyBatis 不会修改或转义字符串。


27、Mybatis获取上一次自动生成的主键值?

对于某些特殊需求:得到刚刚插入数据的主键值,以便对刚刚生成的数据做处理 。

在数据库操作时,对表的插入操作时,主键很多时候会采用nextval(‘num_seq’)这种形式,这种情况下,插入数据完成之后不知道主键的值,而有时候我们需要用到这个值,这时候再重新去查询一次数据库就感觉有些麻烦,这时候可以在mapper.xml文件中的语句中这样处理

<insert id="insertPerson" parameterType="com.PersonEntity" useGeneratedKeys="true" keyProperty="personId" >
        INSERT INTO t_person(
            person_id,
            person_name,
            sex,
            updater,
            register_date,
            renewal_date)
        VALUES (nextval('num_seq'),
            #{enterpriseId},
            #{personName},
            #{sex},
            #{updater},
            current_timestamp(3),
            current_timestamp(3));
    </insert>

useGeneratedKeys设置为true,设定keyProperty的值为在Entity里面的字段名,在service里面可以直接用get处理取得插入的字段值。

personMapper.insertPerson(entity);
String personId = entity.getPersonId(); 

28、Mybatis如何分页,分页原理?

  • RowBounds对象分页

  • 在Sql内直接书写,带有物理分页

①分页插件的实现原理是什么?

Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页,可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。 Mybatis 使用 JDK 的动态代理,在插件的拦截方法内拦截待执行的 SQL,然后重写 SQL,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。

②MyBatis 逻辑分页和物理分页的区别?

逻辑分页是一次性查询很多数据,然后再在结果中检索分页的数据。这样做弊端是需要消耗大量的内存、有内存溢出的风险、对数据库压力较大。

物理分页是从数据库查询指定条数的数据,弥补了一次性全部查出的所有数据的种种缺点,比如需要大量的内存,对数据库查询压力较大等问题。


29、Mybatis工作原理

 

工作原理:

  • 通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件中构建出SqlSessionFactory。

  • SqlSessionFactory开启一个SqlSession,通过SqlSession实例获得Mapper对象并且运行Mapper映射的Sql语句。

  • 完成数据库的CRUD操作和事务提交,关闭SqlSession。


30、MyBatis 的一级缓存和二级缓存

MyBatis是常见的Java数据库访问层框架。在日常工作中,开发人员多数情况下是使用MyBatis的默认缓存配置,但是MyBatis缓存机制有一些不足之处,在使用中容易引起脏数据,形成一些潜在的隐患。

MyBatis自带的缓存有一级缓存和二级缓存:

①一级缓存

Mybatis的一级缓存是指Session缓存。一级缓存的作用域默认是一个SqlSession。Mybatis默认开启一级缓存。也就是在同一个SqlSession中,执行相同的查询SQL,第一次会去数据库进行查询,并写到缓存中;第二次以后是直接去缓存中取。当执行SQL查询中间发生了增删改的操作,MyBatis会把SqlSession的缓存清空。

一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION,如果不想使用一级缓存,可以把一级缓存的范围指定为STATEMENT,这样每次执行完一个Mapper中的语句后都会将一级缓存清除。

如果需要更改一级缓存的范围,可以在Mybatis的配置文件中,在下通过localCacheScope指定。建议不需要修改。

<setting name="localCacheScope" value="STATEMENT"/>

注意:当Mybatis整合Spring后,直接通过Spring注入Mapper的形式,如果不是在同一个事务中每个Mapper的每次查询操作都对应一个全新的SqlSession实例,这个时候就不会有一级缓存的命中,但是在同一个事务中时共用的是同一个SqlSession。

如有需要可以启用二级缓存。

②二级缓存

Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。Mybatis需要手动设置启动二级缓存。

二级缓存是默认启用的(要生效需要对每个Mapper进行配置),如想取消,则可以通过Mybatis配置文件中的元素下的子元素来指定cacheEnabled为false

<settings>

  <setting name="cacheEnabled" value="false" />

</settings>

cacheEnabled默认是启用的,只有在该值为true的时候,底层使用的Executor才是支持二级缓存的CachingExecutor。具体可参考Mybatis的核心配置类org.apache.ibatis.session.Configuration的newExecutor方法实现。

美团技术团队:聊聊MyBatis缓存机制


31、MyBatis 与 Hibernate 的区别?

1) Mybatis 学习门槛低,简单易学,程序员直接编写原生态 sql

2) mybatis 可以通过 XML 或注解方式灵活配置要运行的 sql 语句,并将 java 对象和 sql 语句映射生成最终执行的 sql,最后将 sql 执行的结果再映射生成 java 对象。

3) MyBatis灵活度高,适合需求变化频繁

 Hibernate是一个开放源的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,建立对象与数据库表的映射。是一个全自动的、完全面向对象的持久层框架,程序员可以不用精通SQL,只要懂得操作POJO就能够操作对应数据库的表;而Mybatis是一个半自动化的持久层框架,需要手动编写sql语句。也就是说Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射略显麻烦,不过Mybatis可以进行更为细致的SQL优化以减少不必要的查询,提高系统性能。

    ①开发方面

        在项目开发过程当中,就速度而言:

            Hibernate开发中,sql语句已经被封装,直接可以使用,加快系统开发;

            Mybatis 属于半自动化,sql需要手工完成,稍微繁琐;

        但是,凡事都不是绝对的,如果对于庞大复杂的系统项目来说,查询语句较多,选择hibernate 就不是一个好方案。

    ②sql优化方面

        Hibernate 自动生成sql,有些语句较为繁琐,会多消耗一些性能;

        Mybatis 手动编写sql,可以避免不需要的查询,提高系统性能;

在管理系统时代,首先是实现业务逻辑,然后才是性能,所以Hibernate在当时是主流。

在移动互联网时代,MyBatis是首选,不屏蔽SQL,程序员可以自己制定SQL规则,能更加精确定义SQL,从而优化性能。更符合互联网高并发,大数据,高性能,高响应的要求。


32、Mybatis中用到的设计模式

   Builder模式,例如SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder;

   工厂模式,例如SqlSessionFactory、ObjectFactory、MapperProxyFactory;

    单例模式,例如ErrorContext和LogFactory;

    代理模式,Mybatis实现的核心,比如MapperProxy、ConnectionLogger,用的jdk的动态代理;还有executor.loader包使用了cglib或者javassist达到延迟加载的效果;

    组合模式,例如SqlNode和各个子类ChooseSqlNode等;

    模板方法模式,例如BaseExecutor和SimpleExecutor,还有BaseTypeHandler和所有的子类例如IntegerTypeHandler;

    适配器模式,例如Log的Mybatis接口和它对jdbc、log4j等各种日志框架的适配实现;

    装饰者模式,例如Cache包中的cache.decorators子包中等各个装饰者的实现;

    迭代器模式,例如迭代器模式PropertyTokenizer;


33、resultType和resultMap区别

使用MyBatis查询数据库记录时,返回类型常用的有两种:resultType和resultMap。SQL语句执行后返回的结果可以使用 Map 存储,也可以使用 POJO 存储。resultMap返回的列名与bean的属性名可以不一致,resultType则要求一致。对于指定resultMap属性,直接读取字符串,而对于指定resultType会解析为具体的类。

  • 简单查询且结果为Pojo类,可以使用resultType;另外,少量查询字段名与Pojo属性名不一致,可以通过使用sql语句别名的方式;

  • 查询字段名与Pojo属性名很多不一致,还有复杂的映射或级联,可以使用resultMap;


四、SpringBoot面试题

34、谈谈你对SpringBoot的理解

①SpringBoot和Spring区别

Spring的缺点分析:

虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring用XML配置,而且是很多XML配置。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。

所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但与此同时它要求的回报也不少。

除此之外,项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。

SpringBoot解决上述Spring的缺点:

SpringBoot对上述Spring的缺点进行的改善和优化,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。

②Spring Boot简介

Spring Boot开发始于 2013 年,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。基于约定优于配置的思想,它默认配置了很多框架的使用方式,从而大大减少开发人员对于Spring框架家族的繁杂配置过程。

就像maven整合了所有的jar包,spring boot整合了很多的框架,同时将其他技术同spring结合起来。通过SpringBoot我们可以很快的搭建一套web项目。spring boot 是微服务框架的起点,他简化了开发过程,配置过程、部署过程、监控过程。

不足:SpringBoot还需要与外围的框架进行集成1)认证鉴定方面2)监控方面等

③SpringBoot的特点

为基于Spring的开发提供更快的入门体验

开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求

提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等

SpringBoot不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式


35、SpringBoot常用注解

@SpringBootApplication: 包含@Configuration、@EnableAutoConfiguration、@ComponentScan

@RestController: 用于标注控制层组件,包含@Controller和@ResponseBody

@Autowired

@Qualifier

@RequestMapping

SpringBootApplication注解简介:

@SpringBootApplication 是 Spring Boot 项目的核心注解,主要目的是开启自动配置。

它是一个组合注解,该注解组合了:@Configuration、@EnableAutoConfiguration、@ComponentScan; 若不是用 @SpringBootApplication 注解也可以使用这三个注解代替。

从Spring3.0,@Configuration用于声明当前类是个配置类,相当于一个Spring配置的xml文件。被注解的类内部包含有一个或多个被@Bean注解的方法,声明当前方法的返回值为一个Bean。AnnotationConfigApplicationContext或 AnnotationConfigWebApplicationContext类会进行扫描,用于构建bean定义,初始 化Spring容器。

其中,@EnableAutoConfiguration 让 Spring Boot 根据类路径中的 jar 包依赖为当前项目进行自动配置,例如,添加了 spring-boot-starter-web 依赖,会自动添加 Tomcat 和 Spring MVC 的依赖,那么 Spring Boot 会对 Tomcat 和 Spring MVC 进行自动配置。(这也是我们上面为啥不用配置spring-mvc.xml的原因,因为已经SpringBoot已经帮我们自动配置好了)

@ComponentScan (cn.test.demo): 自动扫描包名下所有使用 @Component @Service  @Repository @Controller 的类,并注册为Bean。于是 Spring Boot 还会自动扫描 @SpringBootApplication 所在类的同级包以及下级包里的 Bean ,所以入口类建议就配置在grounpID + arctifactID 组合的包名下(这里为 com.hs.springboot demo包)


36、什么是SpringBoot Starter?

SpringBootstarter可以理解成pom配置了一堆jar组合的空maven项目,用来简化maven依赖配置,减少依赖包的版本冲突,starter可以继承也可以依赖于别的starter。


37、讲一下SpringBoot的四大核心功能

起步依赖机制:通过起步依赖机制(Starter),简化jar包的引用,解决jar版本冲突问题。

自动配置:可以实现简单配置,甚至是零配置,就能搭建整套框架。

StringBoot CLI(命令行界面):一种命令工具。

Actuator:是SpringBoot的程序监控器,可监控Spring应用程序上下文中的Bean、查看自动配置决策、Controller映射、线程活动、应用程序健康状况等。


38、Springboot支持哪些嵌入式容器?

SpringBoot是默认采用ssm架构,里面的日志采用的是logback ,嵌入式的tomcat容器。

springboot支持三种嵌入式servlet容器:Apache的tomcat(默认)、Eclipse基金会的jetty和undertow


39、SpringBootApplication自动配置如何实现的?

①什么是SpringBoot自动配置?

​ SpringBoot的自动配置,指的是SpringBoot会自动将一些配置类的bean注册进ioc容器,我们可以需要的地方使用@autowired或者@resource等注解来使用它。

​ “自动”的表现形式就是我们只需要引我们想用功能的包,相关的配置我们完全不用管,springboot会自动注入这些配置bean,我们直接使用这些bean即可。

②SpringBoot如何实现自动配置?

其实说白了SpringBoot的自动配置,实际是依赖@Conditional来实现的。@Conditional是一个条件注解,是Spring4提供的一个新特性,用于根据特定条件来控制Bean的创建行为。

简单详细的SpringBoot自动配置原理解析


参考链接:

《我想进大厂》之Spring夺命连环10问

更多推荐

SSM框架和SpringBoot高频率面试题