栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

实战:自定义简易版SpringBoot

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

实战:自定义简易版SpringBoot

实战:自定义简易版SpringBoot
一、功能要求

自定义简易版SpringBoot,实现SpringBoot MVC及内嵌Tomcat启动、DispatcherServlet注册和组件扫描功能

程序通过main方法启动,可以自动启动tomcat服务器

可以自动创建和加载DispatcherServlet组件到ServletContext中

可以自动通过@ComponentScan扫描Controller等组件

Controller组件可以处理浏览器请求,返回响应结果
二、实现思路分析

传统SpringMVC框架web.xml的配置内容:


   
   
       org.springframework.web.context.ContextLoaderListener
   
   
   
       contextConfigLocation
       /WEB-INF/app-context.xml
   
   
   
       app
       org.springframework.web.servlet.DispatcherServlet
       
           contextConfigLocation
           
       
       1
   
   
       app
       /app/*
   

Spring官方文档中给出了基于Servlet3.0规范如何使用Java代码实现web.xml配置的example

public class MyWebApplicationInitializer implements WebApplicationInitializer {

   @Override
   public void onStartup(ServletContext servletCxt) {

       // Load Spring web application configuration
       //通过注解的方式初始化Spring的上下文
       AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
       //注册spring的配置类(替代传统项目中xml的configuration)
       ac.register(AppConfig.class);
       ac.refresh();

       // Create and register the DispatcherServlet
       //基于java代码的方式初始化DispatcherServlet
       DispatcherServlet servlet = new DispatcherServlet(ac);
       ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
       registration.setLoadOnStartup(1);
       registration.addMapping("/app/*");
   }
}

当实现了Servlet3.0规范的容器(比如Tomcat7及以上版本)启动时

  1. 会通过SPI扩展机制自动扫描所有jar包里meta-INF/services/javax.servlet.ServletContainerInitializer文件中指定的全路径类(该类需实现ServletContainerInitializer接口)
  2. 实例化该类
  3. 回调类中的onStartup方法
  4. 在onStartup方法中,可以回调WebApplicaitonInitializer的onStartup方法
  5. 在WebApplicaitonInitializer的onStartup方法中 进行传统SpringMVC框架web.xml的 内容配置

三、编码(实现方式一:使用框架的SpringServletContainerInitializer)

(1)创建maven工程,导入以下依赖:

    
        
            org.springframework
            spring-web
            5.0.8.RELEASE
        
        
            org.apache.tomcat.embed
            tomcat-embed-core
            8.5.32
        
        
            org.apache.tomcat.embed
            tomcat-embed-jasper
            8.5.32
        
        
            org.springframework
            spring-context
            5.0.8.RELEASE
        
        
            org.springframework
            spring-webmvc
            5.0.8.RELEASE
        
    

(2)创建SpringApplication类,编写run方法(方法中要求完成tomcat的创建及启动)

public class SpringApplication {

    public static void run(){
        //创建tomcat实例
        Tomcat tomcat = new Tomcat();
        //设置tomcat端口
        tomcat.setPort(8888);
        try {
            //设置项目文件路径
            tomcat.addWebapp("/", "G:\");
            //启动tomcat
            tomcat.start();
            // 监听关闭端口,阻塞式。没有这一句,方法执行完会直接结束
            tomcat.getServer().await();
        } catch (LifecycleException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }
}

(3)创建spring的配置类 AppConfig该类上要通过@ComponentScan来进行包扫描

@Configuration
@ComponentScan("com.dabing")
public class AppConfig {
    {
        System.out.println("ComponentScan...........");
    }
}

(4)创建MyWebApplicationInitializer实现WebApplicationInitializer接口,重写onstartup方法(WebApplicationInitializer实现web.xml的配置)

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext servletContext) throws ServletException {
        System.out.println("初始化 MyWebApplicationInitializer");
        //通过注解的方式初始化Spring的上下文
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        //注册spring的配置类(替代传统项目中xml的configuration)
        ac.register(AppConfig.class);

        // Create and register the DispatcherServlet
        //基于java代码的方式初始化DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletContext.addServlet("/", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/*");
    }
}

(5)编写一个Controller测试类及目标方法,响应输出“hello”即可

@RestController
public class TestController {

    @RequestMapping("/test/hello")
    public String test(){
        System.out.println("--- hello ---");
        return "hello";
    }

}

(6)编写一个启动类Main,通过执行main方法启动服务

public class Main {

    public static void main(String[] args) {
        SpringApplication.run();
    }
}

(7)通过浏览器对目标方法进行方法

四、编码(实现方式二:自定义MySpringServletContainerInitializer)

(1)创建maven工程,导入以下依赖:

    
        
            org.springframework
            spring-web
            5.0.8.RELEASE
        
        
            org.apache.tomcat.embed
            tomcat-embed-core
            8.5.32
        
        
            org.apache.tomcat.embed
            tomcat-embed-jasper
            8.5.32
        
        
            org.springframework
            spring-context
            5.0.8.RELEASE
        
        
            org.springframework
            spring-webmvc
            5.0.8.RELEASE
        
    

(2)创建SpringApplication 类,编写run方法(方法中要求完成tomcat的创建及启动)

public class SpringApplication {

    public static void run(){
        //创建tomcat实例
        Tomcat tomcat = new Tomcat();
        //设置tomcat端口
        tomcat.setPort(8888);
        try {
            //设置项目文件路径
            tomcat.addWebapp("/", "G:\");
            //启动tomcat
            tomcat.start();
            // 监听关闭端口,阻塞式。没有这一句,方法执行完会直接结束
            tomcat.getServer().await();
        } catch (LifecycleException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }
}

(3)创建spring的配置类 AppConfig该类上要通过@ComponentScan来进行包扫描

@Configuration
@ComponentScan("com.dabing")
public class AppConfig {
    {
        System.out.println("ComponentScan...........");
    }
}

(4)创建MySpringServletContainerInitializer,实现ServletContainerInitializer接口,重写onstartup方法,方法中调用第4步中MyWebApplicationInitializer的onstartup方法

@HandlesTypes(MyWebApplicationInitializer.class)
public class MySpringServletContainerInitializer implements ServletContainerInitializer {
    public void onStartup(Set> webAppInitializerClasses, ServletContext servletContext) throws ServletException {

        System.out.println("初始化 MySpringServletContainerInitializer");
        List initializers = new linkedList();
        if (webAppInitializerClasses != null) {
            for (Class waiClass : webAppInitializerClasses) {
                if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
                        WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                    try {
                        initializers.add((WebApplicationInitializer)
                                ReflectionUtils.accessibleConstructor(waiClass).newInstance());
                    } catch (Throwable ex) {
                        throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
                    }
                }
            }
        }
        if (initializers.isEmpty()) {
            servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
            return;
        }
        servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
        AnnotationAwareOrderComparator.sort(initializers);
        for (WebApplicationInitializer initializer : initializers) {
            System.out.println("for--------------");

            initializer.onStartup(servletContext);
        }
    }
}

(5)创建文件:meta-INF/services/javax.servlet.ServletContainerInitializer,在该文件中配置ServletContainerInitializer的实现类MySpringServletContainerInitializer

com.dabing.web.MySpringServletContainerInitializer

(6)创建MyWebApplicationInitializer实现WebApplicationInitializer接口,重写onstartup方法(WebApplicationInitializer实现web.xml的配置)

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext servletContext) throws ServletException {
        System.out.println("初始化 MyWebApplicationInitializer");
        //通过注解的方式初始化Spring的上下文
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        //注册spring的配置类(替代传统项目中xml的configuration)
        ac.register(AppConfig.class);

        // Create and register the DispatcherServlet
        //基于java代码的方式初始化DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletContext.addServlet("/", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/*");
    }
}

(7)编写一个Controller测试类及目标方法,响应输出“hello”即可

@RestController
public class TestController {

    @RequestMapping("/test/hello")
    public String test(){
        System.out.println("--- hello ---");
        return "hello";
    }

}

(8)编写一个启动类Main,通过执行main方法启动服务

public class Main {

    public static void main(String[] args) {
        SpringApplication.run();
    }
}

(9)通过浏览器对目标方法进行方法

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/314303.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号