Spring Boot如何实现零配置

Spring 专栏收录该内容
3 篇文章 0 订阅

1. Web项目启动的过程

  • Servlet的容器:Tomcat,Jetty,Jboos等,其中Nginx、Apache是http容器;
  • Web.xml配置(配置listener和servlet)
    1. listener需要配置ContextLoaderListener,再通过访问webApplicationContext加载spring上下文,实际就是为了加载spring.xml文件;
web.xml 文件

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/config/spring.xml</param-value>
</context-param>

<listener>
<description>listener</description>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  1. 配置servlet是为了启动spring-MVC, 该过程是通过DispatchServlet访问spring-mvc.xml

web项目的启动流程:Tomcat启动时会解析web.xml文件 → \rightarrow 通过web.xml文件初始化listener和servlet → \rightarrow 执行listener(ContextLoaderListener) 加载spring → \rightarrow 执行servlet(DispatchServlet)加载spring-mvc

2.SpringBoot替换机制

当使用ssm这种架构去完成一个web项目时,你需要去写配置很多内容。例如:web.xml, spring-mvc.xml, spring.xml等。但是在springboot无需要任何配置也能完成web项目,springboot采用约定大于配置的方式完成使用注解的方式实现配置,在内嵌的Tomcat中通过代码的方式代替了web.xml中servlet和listener的配置。
1.内嵌Tomcat代替原生去除web.xml:

<!-- 添加Tomcat的依赖 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.0.48</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.0.48</version>
</dependency>
 <dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>8.0.48</version>
</dependency>

public class MainApplication {
    public static void main(String[] args) throws ServletException, LifecycleException {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(80);
        //获取指定的绝对路径获取上下文
        Context context = tomcat.addWebapp("/", new File("sourceCode/src/main/webapp").getAbsolutePath());
        //此处可通过context设置servlet和listener.
        WebResourceRoot root = new StandardRoot(context);
        String path = MainApplication.class.getResource("").getPath();
        System.out.println(path);
        root.addPreResources(new DirResourceSet(root, "/WEB-INF/classes", path, "/"));
        context.setResources(root);
        tomcat.start();
        tomcat.getServer().await();
    }
}
<!DOCTYPE html>
<html>
<head>Hello World</head>
</html>

运行后通过localhost:80/index.html访问到Hello World即表示成功
Note: 1. 在获取绝对路径并访问该绝对路径下的index.html文件时,会存在忽略模块名这一项导致找不到文件报错,后来我把模块名加上才成功启动

2.使用注解代替spring.xml
采用AnnotationConfigApplicationContext替换AbstractXmlApplicationContext,主要的一些注解包括:@Configuration, @Bean, @Service,@ComponentScan, @Component, @MapperScan, @Mapper
完成一下伪代码:

  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        //将配置注册到context容器中
        context.register(xxxConfig.class);
        //容器刷新获取最新的所有bean
        context.refresh();
        //根据class对象获取该对象的bean
        XxxMapper xxxMapper = context.getBean(XxxMapper.class);
        //业务使用
        xxxMapper.getUser(userId);

3.代替spring-mvc.xml
目前官网也推荐使用代码的方式配置DispatchServlet:点击进入

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.12.RELEASE</version>
<scope>compile</scope>
</dependency>

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(AppConfig.class);

        // Create and register the DispatcherServlet 之前此处应该是配在xml文件中的
        DispatcherServlet servlet = new DispatcherServlet(context);
        ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
}

onStartup方法替换web.xml, 完成初始化IOC容器和初始化servlet,因此Tomcat启动总是会加载MyWebApplicationInitializer中的onStartup方法完成这两个重要的过程。

Tomcat启动会加载MyWebApplicationInitializer原因:由于在java的servlet中有个接口ServletContainerInitializer, Spring使用SpringServletContainerInitializer实现了该接口,然后又声明了WebApplicationInitializer接口供开发者使用,在通过@HandlesTypes注解将二者关联在一起,因此会调用开发者所有实现该接口中的onStartup方法。
ServletContainerInitializer 是 servlet3.0 提供的一个 SPI(Service Provider Interface),可以通过 HandlesTypes 筛选出相关的 servlet 类。

  • 0
    点赞
  • 2
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值