Spring面试题

文章目录

Spring

1 什么是Spring

Spring是一个轻量级的无入侵性的IOC和AOP框架

2 使用Spring框架的好处是什么?

  • 轻量:Spring 是轻量的,基本的版本大约2MB

  • 控制反转(IOC):Spring通过控制反转实现了松散耦合,对像们给出它们的依赖,而不是创建或查找依赖的对象们

  • 面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开

  • 容器:Spring 包含并管理应用中对象的生命周期和配置

  • 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)

3 什么是Spring IOC 容器?

Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。

4 什么是控制反转(IOC)?什么是依赖注入?

IOC是一种思想。在传统的JavaSE程序设计中,我们要使用对象要通过new创建,即应用程序主动创建对象,而Spring提供了一个IOC容器,对象的创建和管理都由容器进行。即容器控制对象,对象创建的控制权被反转了。

依赖注入DI是Spring IOC思想的实现方式,有两种注入方式:构造方法注入和setter注入

5 什么是Spring beans?

Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中<bean/> 的形式定义。

6 你怎样定义类的作用域?

当定义一个<bean> 在Spring里,我们还能给这个bean声明一个作用域。它可以通过bean 定义中的scope属性来定义。如,当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。另一方面,一个bean每次使用的时候必须返回同一个实例,这个bean的scope 属性 必须设为 singleton。

注解可以使用 @Scope

7 Spring框架中的单例bean是线程安全的吗?

不,Spring框架中的单例bean不是线程安全的。

8 Spring 的生命周期

四个阶段

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

9 bean的生命周期能否被干预? 如何干预

可以,有三种方式可以

  • 我们可以通过@PostConstruct 和 @PreDestroy 这2个注解在bean的初始化完成和销毁之前实现一些逻辑操作。

  • 使用@Bean注解的initMethod和destroyMethod属性指定生命周期回调(函数|方法)

  • 实现 Spring 的接口,通过实现 Spring 的 InitializingBean 和 DisposableBean 这2个接口来实现的

10 什么是bean装配?

装配,或bean 装配是指在Spring 容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起

11 @Required 注解

这个注解表明bean的属性必须在配置的时候设置,通过一个bean定义的显式的属性值或通过自动装配,若@Required注解的bean属性未被设置,容器将抛出
BeanInitializationException。

12 Spring支持的事务管理类型

Spring支持两种类型的事务管理:

  • 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
  • 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

13 AOP有哪些实现方式?

AOP有两种实现方式:静态代理和动态代理。

静态代理

静态代理:代理类在编译阶段生成,在编译阶段将通知织入Java字节码中,也称编译时增强。AspectJ使用的是静态代理。

缺点:代理对象需要与目标对象实现一样的接口,并且实现接口的方法,会有冗余代码。同时,一旦接口增加方法,目标对象与代理对象都要维护。

动态代理

动态代理:代理类在程序运行时创建,AOP框架不会去修改字节码,而是在内存中临时生成一个代理对象,在运行期间对业务方法进行增强,不会生成新类。

14 JDK动态代理和CGLIB动态代理的区别?

Spring AOP中的动态代理主要有两种方式:JDK动态代理和CGLIB动态代理。

JDK动态代理

如果目标类实现了接口,Spring AOP会选择使用JDK动态代理目标类。代理类根据目标类实现的接口动态生成,不需要自己编写,生成的动态代理类和目标类都实现相同的接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。

缺点:目标类必须有实现的接口。如果某个类没有实现接口,那么这个类就不能用JDK动态代理。

CGLIB来动态代理

通过继承实现。如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library)可以在运行时动态生成类的字节码,动态创建目标类的子类对象,在子类对象中增强目标类。

CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

优点:目标类不需要实现特定的接口,更加灵活。

两者的区别

  1. jdk动态代理使用jdk中的类Proxy来创建代理对象,它使用反射技术来实现,不需要导入其他依赖。cglib需要引入相关依赖:asm.jar,它使用字节码增强技术来实现。
  2. 当目标类实现了接口的时候,Spring Aop默认使用jdk动态代理方式来增强方法,没有实现接口的时候使用cglib动态代理方式增强方法。

15 Bean注入容器有哪些方式?

将普通类交给Spring容器管理,通常有以下方法:

1、使用@Configuration@Bean注解;

2、使用@Controller@Service@Repository@Component 注解标注该类,然后启用@ComponentScan自动扫描;

3、使用@Import 方法。使用@Import注解把Bean导入到容器中,代码如下:

@ComponentScan
@Import({Demo.class})
public class App {
    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
        System.out.println(context.getBean(Demo.class));
        context.close();
    }
}

16 @Autowired和@Resource的区别?

1、@Autowired注解是按照类型byType装配依赖对象的,但是如果存在多个类型⼀致的Bean,⽆法通过byType注⼊时,就会使⽤byName根据名称来注⼊。byName是将bean的名字与被注入的成员变量的名称匹配,而不是与被注入的成员变量的类型匹配。以下代码中,App 类的成员变量 userService1 会使用名字为 userService1 的 Bean,成员变量 userService2 会使用名字为 userService2 的 Bean。

@Service
class UserService1 implements UserService {...}
@Service
class UserService2 implements UserService {...}

public class App {
    @Autowired
    private UserService userService1;
    @Autowired
    private UserService userService2;

    @Test
    public void test() {
        System.out.println(userService1.getClass().toString());
        System.out.println(userService2.getClass().toString());
    }
}

如果⽆法判断注⼊哪个Bean则会抛出UnsatisfiedDependencyException

2、@Resource会⾸先按照名称byName来装配,如果找不到Bean,会⾃动byType再找⼀次。

17 @Qualifier 注解有什么作用

当需要创建多个相同类型的 Bean 并希望仅使用属性装配其中一个 Bean 时,可以使用@Qualifier注解和 @Autowired 通过指定应该装配哪个 Bean 来消除歧义。

@Component("bird")
public class Bird implements Fly {...}

@Component("plane")
public class Plane implements Fly {...}

@Component
public class FooService {
    @Autowired
    @Qualifier("bird")
    private Fly fly;
}

18 @Bean和@Component有什么区别?

都是使用注解定义 Bean。两者的区别:

1、@Bean 是使用 Java 代码装配 Bean,@Component 是自动装配 Bean。

2、@Component 注解用在类上,表明一个类会作为组件类,并告知Spring要为这个类创建Bean,每个类对应一个 Bean。而@Bean 注解用在方法上,表示这个方法会返回一个 Bean。@Bean 需要在配置类中使用,即类上需要加上@Configuration注解。

@Component
public class Student {...}

@Configuration
public class WebSocketConfig {
    @Bean
    public Student student(){
        return new Student();
    }
}

@Bean 注解更加灵活。当需要将第三方类装配到 Spring 容器中,因为没办法源代码上添加@Component注解,只能使用@Bean注解的方式,当然也可以使用 xml 的方式。

19 @Component、@Controller、@Repositor和@Service 的区别?

@Component:最普通的组件,可以被注入到spring容器进行管理。

@Controller:将类标记为 Spring Web MVC 控制器。

@Service:业务层组件。

@Repository:数据访问组件,即DAO组件。

20 Spring 事务实现方式有哪些?

事务就是一系列的操作原子执行。Spring事务机制主要包括声明式事务和编程式事务。

  • 编程式事务:通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。
  • 声明式事务:将事务管理代码从业务方法中分离出来,通过aop进行封装。Spring声明式事务使得我们无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。使用 @Transactional 注解开启声明式事务。

@Transactional相关属性如下:

属性类型描述
valueString可选的限定描述符,指定使用的事务管理器
propagationenum: Propagation可选的事务传播行为设置
isolationenum: Isolation可选的事务隔离级别设置
readOnlyboolean读写或只读事务,默认读写
timeoutint (in seconds granularity)事务超时时间设置
rollbackForClass对象数组,必须继承自Throwable导致事务回滚的异常类数组
rollbackForClassName类名数组,必须继承自Throwable导致事务回滚的异常类名字数组
noRollbackForClass对象数组,必须继承自Throwable不会导致事务回滚的异常类数组
noRollbackForClassName类名数组,必须继承自Throwable不会导致事务回滚的异常类名字数组

21 有哪些事务传播行为?

在TransactionDefinition接口中定义了七个事务传播行为:

  1. PROPAGATION_REQUIRED 默认传播方式,如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。如果嵌套调用的两个方法都加了事务注解,并且运行在相同线程中,则这两个方法使用相同的事务中。如果运行在不同线程中,则会开启新的事务。
  2. PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。
  3. PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果不存在事务,则抛出异常IllegalTransactionStateException
  4. PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。需要使用JtaTransactionManager作为事务管理器。
  5. PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。需要使用JtaTransactionManager作为事务管理器。
  6. PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常。
  7. PROPAGATION_NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务, 则按PROPAGATION_REQUIRED 属性执行。

PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别:

使用PROPAGATION_REQUIRES_NEW时,内层事务与外层事务是两个独立的事务。一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。

使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。

22 Spring怎么解决循环依赖的问题?

构造器注入的循环依赖:Spring处理不了,直接抛出 BeanCurrentlylnCreationException 异常。
非单例循环依赖:无法处理。

单例模式下属性注入的循环依赖:通过三级缓存处理循环依赖。
首先,Spring单例对象的初始化大略分为三步:

  1. createBeanInstance:实例化Bean,使用构造方法创建对象,为对象分配内存。
  2. populateBean:进行依赖注入。
  3. initializeBean:初始化Bean。

Spring为了解决单例的循环依赖问题,使用了三级缓存

singletonObjects:完成了初始化的单例对象map

earlySingletonObjects:完成实例化未初始化的单例对象map

singletonFactories:单例对象工厂map,单例对象实例化完成之后会加入singletonFactories

在调用createBeanInstance进行实例化之后,会调用addSingletonFactory,将单例对象放到singletonFactories中。addSingletonFactory源码如下:

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

假如A依赖了B的实例对象,同时B也依赖A的实例对象。

  1. A首先完成了实例化,并且将自己添加到singletonFactories
  2. 接着进行依赖注入,发现自己依赖对象B,此时就尝试去get(B)
  3. 发现B还没有被实例化,对B进行实例化
  4. 然后B在初始化的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存singletonObjects和二级缓存earlySingletonObjects没找到,尝试三级缓存singletonFactories,由于A初始化时将自己添加到了singletonFactories,所以B可以拿到A对象,然后将A从三级缓存中移到二级缓存中
  5. B拿到A对象后顺利完成了初始化,然后将自己放入到一级缓存singletonObjects
  6. 此时返回A中,A此时能拿到B的对象顺利完成自己的初始化

总结:1、缓存已经遍历过的节点;2、提前设置对象地址,后完善对象。

23 Spring 的单例 Bean 是否有线程安全问题?

当多个用户同时请求一个服务时,容器会给每一个请求分配一个线程,这时多个线程会并发执行该请求对应的业务逻辑,如果业务逻辑有对单例状态的修改(单例的成员属性),则必须考虑线程安全问题。

若每个线程中对全局变量、静态变量只有读操作,而无写操作,那么不会有线程安全问题;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。

无状态Bean和有状态Bean

  • 有实例变量的Bean,可以保存数据,是非线程安全的。
  • 没有实例变量的对象。不能保存数据,是线程安全的。

在Spring中无状态的Bean适合用单例模式,这样可以共享实例提高性能。有状态的Bean在多线程环境下不安全,可以用设置Bean为Prototype模式或者使用ThreadLocal解决线程安全问题。

24 Spring 用到了哪些设计模式?

1、简单工厂模式BeanFactory就是简单工厂模式的体现,根据传入一个唯一标识来获得 Bean 对象。

@Override
public Object getBean(String name) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(name);
}

2、工厂方法模式FactoryBean就是典型的工厂方法模式。spring在使用getBean()调用获得该Bean时,会自动调用该Bean的getObject()方法。每个 Bean 都会对应一个 FactoryBean,如 SqlSessionFactory 对应 SqlSessionFactoryBean

3、单例模式:一个类仅有一个实例。Spring 创建 Bean 实例默认是单例的。

4、适配器模式:SpringMVC中的适配器HandlerAdatper。由于应用会有多个Controller实现,如果需要直接调用Controller方法,那么需要先判断是由哪一个Controller处理请求,然后调用相应的方法。当增加新的 Controller,需要修改原来的逻辑,违反了开闭原则(对修改关闭,对扩展开放)。

为此,Spring提供了一个适配器接口,每一种 Controller 对应一种 HandlerAdapter 实现类,当请求过来,SpringMVC会调用getHandler()获取相应的Controller,然后获取该Controller对应的 HandlerAdapter,最后调用HandlerAdapterhandle()方法处理请求,实际上调用的是Controller的handleRequest()。每次添加新的 Controller 时,只需要增加一个适配器类就可以,无需修改原有的逻辑。源码如下:

// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

public class HttpRequestHandlerAdapter implements HandlerAdapter {

    @Override
    public boolean supports(Object handler) {//handler是被适配的对象,这里使用的是对象的适配器模式
        return (handler instanceof HttpRequestHandler);
    }

    @Override
    @Nullable
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {

        ((HttpRequestHandler) handler).handleRequest(request, response);
        return null;
    }
}

5、代理模式:spring 的 aop 使用了动态代理,有两种方式JdkDynamicAopProxyCglib2AopProxy

6、模板模式:Spring 中 jdbcTemplatehibernateTemplate 等使用了模板模式。

25 Spring事务在什么情况下会失效

  • 在方法中使用了try catch,这时候try块中的代码块就会脱离事务的控制,若需要事务生效需要在catch中抛出异常
  • 使用了非public修饰符
  • 对象未被spring管理

26 什么是AOP

AOP就是面向切面编程,将公共逻辑封装为切面,与业务代码进行分离,可以减少重复代码和降低模块之间的耦合性。

SpringMVC

1 什么是Spring MVC ?简单介绍下你对springMVC的理解?

Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

2 SpringMVC的流程?

(1)用户发送请求至前端控制器DispatcherServlet;
(2)DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handler;
(3)处理器映射器根据请求url找到具体的处理器Handler,生成处理器对象及处理器拦截器(如果有则生成),一并返回给DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter处理器适配器,请求执行Handler;
(5)HandlerAdapter 经过适配调用 具体处理器进行处理业务逻辑;
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。

在这里插入图片描述

3 SpringMVC常用的注解有哪些?

@Controller

@Controller用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller对象。处理器适配器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。

@RequestMapping

@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。返回值会通过视图解析器解析为实际的物理视图,对于 InternalResourceViewResolver 视图解析器,通过 prefix + returnValue + suffix 这样的方式得到实际的物理视图,然后做转发操作。

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>

@ResponseBody

@ResponseBody把Java对象转化为json对象,这种方式用于Ajax异步请求,返回的不是一个页面而是JSON格式的数据。

@PathVariable

@PathVariable用于接收uri地址传过来的参数,Url中可以通过一个或多个{Xxx}占位符映射,通过@PathVariable可以绑定占位符参数到方法参数中,在RestFul接口风格中经常使用。
例如:请求URL:http://localhost/user/21/张三/query
(Long类型可以根据需求改变为String或int,SpringMVC会自动做转换)

@RequestMapping("/user/{userId}/{userName}/query")
public User query(@PathVariable("userId") Long userId, @PathVariable("userName") String userName){

}

@RequestParam

@RequestParam用于将请求参数映射到控制器方法的形参上,有如下三个属性

value:参数名。
required:是否必需,默认为true,表示请求参数中必须包含该参数,如果不包含抛出异常。
defaultValue:默认参数值,如果设置了该值自动将required设置为false,如果参数中没有包含该参数则使用默认值。
示例:@RequestParam(value = “pageNum”, required = false, defaultValue = “1”)

4 SpingMvc中的控制器的注解一般用哪个?有没有别的注解可以替代?

答:一般用@Controller注解,也可以使用@RestController,@RestController注解相当于@ResponseBody + @Controller,表示是表现层,除此之外,一般不用别的注解代替。

5 POST 和 GET 请求有什么区别

1、URL形式
get将表单中数据按照name=value的形式,添加到action 所指向的URL 后面,并且两者使用”?”连接,而各个变量之间使用”&”连接
post请求:post请求会把请求的数据放置在HTTP请求包的包体中,传递到action所指向URL。上面的item=bandsaw就是实际的传输数据。
因此,get请求的数据会暴露在地址栏中,而POST请求则不会。
get请求用来从服务器上获得资源,而post是用来向服务器提交数据;
2、传输数据的大小
在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于get,特定的浏览器和服务器对URL的长度有限制。因此,在使用get请求时,传输数据会受到URL长度的限制。
对于post,由于不是URL传值,理论上是不会受限制的,上传文件通常要使用post方式;但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。
3、安全性
post的安全性比get的高。这里的安全是指真正的安全,而不同于上面get提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过get请求,用户名和密码都会暴露再URL上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。除此之外,get请求提交的数据还可能会造成Cross-site request frogery攻击。
如果这些数据不是敏感数据,那么可以使用get;对于敏感数据还是应用使用post;
注意:GET方式提交表单的典型应用是搜索引擎。GET方式就是被设计为查询用的。

6 如果在拦截请求中,我想拦截get方式提交的方法,怎么配置?

可以在@RequestMapping注解里面加上method=RequestMethod.GET。

7 怎样在方法里面得到Request,或者Session?

直接在方法的形参中声明request,SpringMvc就自动把request对象传入。

8 怎样在方法里面得到Request,或者Session?

直接在方法的形参中声明request 或者Session,SpringMvc就自动把request对象或者Session对象传入。

9 如果想在拦截的方法里面得到从前台传入的参数,怎么得到?

直接在形参里面声明这个参数就可以,但必须名字和传过来的参数字段名称一样。

10 如果前端传入多个参数,并且参数都是同个对象的,如何快速得到这个对象?

构造对象接收参数,SpringMvc就自动会把属性赋值到这个对象里面。

11 SpringMvc中函数的返回值是什么?

返回值可以有很多类型,有String,ModelAndView。ModelAndView类把视图和数据都合并的一起的,但一般用String比较好。

12 SpringMvc用什么对象从后台向前台传递数据的?

通过ModelMap对象,可以在这个对象里面调用put方法,把对象加到里面,前端就可以通过el表达式拿到。

13 怎么样把ModelMap里面的数据放入Session里面?

可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key。

14 你是怎么解决前后端分离中的跨域问题的

跨域问题解决办法有三种:

  1. 后端给跨域的controller加@CrossOrigin注解
  2. 后端定义拦截器
  3. 前端加代理proxy代理到后端地址

15 什么是跨域问题,跨域问题是怎么产生的

从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域,跨域是由于浏览器的同源策略产生的

SpringBoot

1 什么是Spring Boot Starter

1、Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包,并且不需要关系版本。如你想使用 Spring JPA 访问数据库,只要加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。
Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。

2、Starters命名
Spring Boot官方的启动器都是以spring-boot-starter-命名的,代表了一个特定的应用类型。
第三方的启动器不能以spring-boot开头命名,它们都被Spring Boot官方保留。一般一个第三方的应该这样命名,像mybatis的mybatis-spring-boot-starter。

2 什么是SpringBoot?

用来简化spring应用的初始搭建以及开发过程,使用特定的方式来进行配置(properties或yml文件)创建独立的spring引用程序 main方法运行,嵌入的Tomcat 无需部署war文件,简化maven配置,自动配置spring添加对应功能starter自动化配置
,简而言之:
SpringBoot来简化Spring应用开发,约定大于配置,去繁化简

3 SpringBoot 的核心注解是哪个?它主要由哪几个注解组成的?

启动类上面的注解是@SpringBootApplication,它也是 SpringBoot 的核心注解,主要组合包含了以下 3 个注解:

@SpringBootConfiguration:组合了 @Configuration 注解,表明了启动类其实也是个配置类,实现配置文件的功能。

@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })

@ComponentScan:Spring组件扫描。SpringBoot默认会扫描启动类当前目录及其子目录中的组件

4 SpringBoot自动配置的原理

SpringBoot是通过启动类的@SpringBootApplication注解进行开始解析的,他会根据@EnableAutoConfiguration开启自动化配置, 里面有个核心方法ImportSelect选择性的导入,通过loadFanctoryNames方法根据classpash路径以MATA-INF/spring.factories下面以EnableAutoConfiguration结尾的key去加载里面所有对应的自动化配置,他并不是把这一百二十多个自动化配置全部导入,在他每个自动化配置里面都有条件判断注解@ConditionalXX,先判断是否引入相互的jar包,再判断容器是否有bean,再进行注入到bean容器

5 你如何理解 Spring Boot 配置加载顺序?

Spring Boot配置加载顺序优先级是:propertiese文件、YAML文件、系统环境变量、命令行参数

6 application.properties和bootstrap.properties有何区别;

bootstrap比 applicaton 优先加载,配置在应用程序上下文的引导阶段生效, 而且boostrap 里面的属性不能被覆盖; application用于 spring boot 项目的自动化配置

7 SpringBoot工程的运行方式

1.打包运行 java -jar sp
2.插件启动
3.启动类main方法启动

8 SpringBoot有什么优点

  • 可以独立运行,SpringBoot内置了Servlet容器,可以单独打成Jar包运行。
  • 简化配置,SpringBot内置许多场景启动器,一键配置开发场景所需所有依赖
  • 自动配置,可以根据当前路径下的依赖自动配置bean

9 SpringBoot 如何读取配置

  1. @Value注解读取
  2. 使用Environment对象获取全部配置属性
  3. @ConfigurationProperties 整体注入
    当属性数量多的时候,采用@Value一个一个注入效率十分低下,这时候我们可以使用@ConfigrationProperties

10 什么是Spring Initializer?

快速生成SpringBoot工程
Spring Initializer是一个网络应用程序,它可以生成一个Spring Boot项目,包含快速启动所需的一切。和往常一样,我们需要一个好的项目框架;它有助于你正确创建项目结构/框架。

11 为什么我们需要 spring-boot-maven-plugin?

spring-boot-maven-plugin 提供了一些像 jar 一样打包或者运行应用程序的命令。
1、spring-boot:run 运行你的 SpringBooty 应用程序。
2、spring-boot:repackage 重新打包你的 jar 包或者是 war 包使其可执行
3、spring-boot:start 和 spring-boot:stop 管理 Spring Boot 应用程序的生命周期(也可以说是为了集成测试)。
4、spring-boot:build-info 生成执行器可以使用的构造信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值