Spring、SpringMVC、SpringBoot面试高频问题

关于Spring、SpringMVC、SpringBoot面试高频问题

Spring的优点

  • 方便解耦,简化开发
  • AOP编程的支持
  • 事务管理
  • 方便调试
  • 方便集成各种优秀的框架

1.Spring,MVC,SpringBoot的区别(简单介绍下Spring,MVC,SpringBoot)

最简练的语言概括就是:

Spring 是一个“引擎”;Spring MVC 是基于Spring的一个 MVC 框架;Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。

Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring 的ioc和 aop。在此两者的基础上实现了其他延伸产品的高级功能。

SpringMVC 提供了一种轻度耦合的方式来开发web应用。它是Spring的一个模块,是一个web框架。使用MVC模式,使得开发web应用变得很容易。

Spring Boot实现了自动配置,降低了项目搭建的复杂度。它主要是为了解决使用Spring框架需要进行大量的配置太麻烦的问题,它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。

2.SpringBoot简化了哪些操作

第一点就是spring的依赖设置很繁琐,原来你导入相关的依赖坐标,可能会产生版本冲突的问题,但是现在springboot已经将版本控制好了,你不用担心版本会产生冲突。

第二点就是spring的配置很繁琐,原来的spring配置bean,配置springmvc,配置web.xml,配置tomcat等等一系列的配置,现在springboot都把这些已经配置好了,都不需要你配置了。

3.延申问题:SpringBoot如何简化(自动配置原理)(SpringBoot启动过程)

在这里插入图片描述

Spring Boot的启动类上有一个@SpringBootApplication注解,@SpringBootApplication是一个复合注解或派生注解,在@SpringBootApplication中有一个注解@EnableAutoConfiguration,是用来开启自动配置的。而这个注解也是一个派生注解,其中的关键功能由@Import提供,其导入的AutoConfigurationImportSelector的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories 的jar包。spring.factories文件也是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表。这个@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(…)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。

4.SpringMVC启动流程

1、 用户向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。
2、DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)
3、DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller
4、HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet
5、DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,然后返回真正的视图。
6、DispatcherServlet将模型数据填充到视图中
7、DispatcherServlet将结果响应给用户

5.Spring 上下文类型

  1. AnnotationConfigApplicationContext 从Java配置类加载Spring应用上下文
  2. AnnotationConfigWebApplicationContext 从Java配置类加载Spring web应用上下文
  3. ClassPathXmlApplicationContext 从类路径下xml配置文件中加载上下文
  4. FilePathXmlApplicationContext 从文件系统路径下xml配置文件中加载上下文
  5. webXmlApplicationContext 从web应用的xml配置文件中加载上下文
//类路径下xml格式的配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xml.url);
//磁盘路径下xml文件配置
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext();
//基于注解、java配置类的方式创建
 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//基于java配置类、用于web环境创建
AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();

6.ApplicationContext&BeanFactory关系

BeanFactory:

是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能;

ApplicationContext:

应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能;

ApplicationContext扩展方法

  • getMessage(),处理国际化信息,可以翻译信息
  • getResource(url),获取资源
  • getEnviroment(),获取环境变量,配置信息(包括yml文件)
  • publishEvent(Event对象),发布事件

BeanFactory不会主动做的事:(解析见下面源码)

  1. 不会主动调用beanfactory后处理器
  2. 不会主动添加bean后处理器
  3. 不会主动实例化bean
  4. 不会解析#{}、${};
两种容器实现详解

BeanFactory

//测试类
class Bean1{
        private String name;
        public Bean1(){
            this.name="bean1";
        }

    }
    class Bean2{
        private String name;
        public Bean2(){
            this.name="bean2";
        }

    }
    @Configuration
    class Config{
        @Bean
        public Bean1 bean1(){
            return new Bean1();
        }
        @Bean
        public Bean2 bean2(){
            return new Bean2();
        }

    }

不能解析注解bean

//创建beanfactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//bean的定义创建        
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
  // bean的注册,注册到beanfactory中
beanFactory.registerBeanDefinition("config",beanDefinition);
/*
config自定义bean
*/

beanfactory功能扩展(扫描config类)

//为beanfactory添加后处理器,实现功能扩展
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        /*
        config自定义bean
        org.springframework.context.annotation.internalConfigurationAnnotationProcessor
        org.springframework.context.annotation.internalAutowiredAnnotationProcessor
        org.springframework.context.annotation.internalCommonAnnotationProcessor
        org.springframework.context.event.internalEventListenerProcessor
        org.springframework.context.event.internalEventListenerFactory
         */

        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        /*
        config自定义bean
        org.springframework.context.annotation.internalConfigurationAnnotationProcessor
        org.springframework.context.annotation.internalAutowiredAnnotationProcessor
        org.springframework.context.annotation.internalCommonAnnotationProcessor
        org.springframework.context.event.internalEventListenerProcessor
        org.springframework.context.event.internalEventListenerFactory
        bean1
        bean2
         */
 //bean后处理器,针对bean的生命周期进行扩展,例如@Autowired
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream().forEach(beanFactory::addBeanPostProcessor);
        //定义容器实例化bean的时机,默认是使用时初始化
        beanFactory.preInstantiateSingletons();//提前实例化单例

7.Springboot配置文件方式:

  1. 在application.properites文件中{形式:server.port = 80}
  2. 创建appliocation.yml文件中{形式:server:port:80} 主流格式
  3. 创建appliocation.yaml文件中{形式:server:port:80}

8.Springboot配置文件优先级(官网给出了更多文件优先级,详情见官网)

properties>yml>yaml

9.Spring AOP五种通知类型

  1. 前置通知@Before()
  2. 后置通知@After()
  3. 环绕通知@Around() //方法需要传参指定何时使用原始方法 ProceedingJoinPoint ptg ptg.proceed()代表原始方法
  4. 返回后通知(了解)@AfterReturning
  5. 抛出异常后通知(了解)@AfterThrowing

10.静态代理和动态代理

静态代理:静态代理就是指我们在给一个类扩展功能的时候,我们需要去书写一个静态的类,相当于在之前的类上套了一层,这样我们就可以在不改变之前的类的前提下去对原有功能进行扩展。

实现方式:静态代理通过一个代理类与被代理对象使用同一个接口(保证方法名相同),然后在代理类里通过组合的相识,吧需要被代理的对象传入,重写的对象中调用被代理对象的方法即可实现。

缺点:若有大量的类需要被代理,则会增大代码量。

动态代理:动态代理简单来说就是在程序执行过程中,创建代理对象,通过代理对象执行方法,给目标类的方法增加额外的功能,也叫做功能增强。

11.动态代理

Jdk动态代理

JDK动态代理主要由JDK提供的Proxy实现。动态代理类是在运行时生成指定接口的代理类,每个代理实例都有一个关联的调用处理程序对象,此对象实现InvocationHandler。
最终的业务逻辑是在InvocationHandler的invoke方法中实现。

CGLIB动态代理

CGLIB动态代理主要通过对字节码的操作,为对象引入间接级别,以控制对象的访问。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值