19.SpringBoot四大神器之CLI和手写SpringBoot

SpringBoot四大神器之CLI和手写SpringBoot

SpringBoot四大神器

SpringBoot 四大神器之四 CLI

CLI简介

​ Spring Boot CLI是一个命令行工具,如果想快速开发Spring应用程序,可以使用它。它可以运行Groovy脚本,这意味着您具有类似Java的熟悉语法,而没有太多样板代码。还可以引导一个新项目或为其编写自己的命令。

下载安装
  • 下载地址:https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.installing

    Spring Boot CLI需要Java JDK v1.8或更高版本才能运行。Groovy已经在发行版包中,无需安装。

image-20220703164918762

  • 解压spring-boot-cli-2.3.5.RELEASE-bin.zip压缩包,到D:\Program Files\spring-2.3.5.RELEASE

image-20220703165052317

  • 配置环境变量SPRINGBOOTCLI

D:\Program Files\spring-2.3.5.RELEASE

  • 安装检查

    运行cmd命令,输入spring --version

    spring --version
    

    image-20220703165252449

使用帮助

查看帮助命令

C:\Users\Admin>spring --help
usage: spring [--help] [--version]
       <command> [<args>]

Available commands are:

  run [options] <files> [--] [args]
  # 运行groovy脚本
    Run a spring groovy script

  grab
    Download a spring groovy script's dependencies to ./repository

	# 通过spring groovy脚本,创建可执行的jar应用
  jar [options] <jar-name> <files>
    Create a self-contained executable jar file from a Spring Groovy script

	# 通过spring groovy脚本,创建包含内嵌容器可执行的war应用
  war [options] <war-name> <files>
    Create a self-contained executable war file from a Spring Groovy script

  install [options] <coordinates>
    Install dependencies to the lib/ext directory

  uninstall [options] <coordinates>
    Uninstall dependencies from the lib/ext directory

	# 通过init命令可以创建并初始化一个springboot项目
  init [options] [location]
    Initialize a new project using Spring Initializr (start.spring.io)

  encodepassword [options] <password to encode>
    Encode a password for use with Spring Security

  shell
    Start a nested shell

Common options:

  --debug Verbose mode
    Print additional status information for the command you are running

# 使用spring help <command>针对指定的命令获得帮助信息
See 'spring help <command>' for more information on a specific command.

C:\Users\Admin>
创建应用
C:\Users\Admin>spring --help init
spring init - Initialize a new project using Spring Initializr (start.spring.io)

usage: spring init [options] [location]

Option                       Description
------                       -----------
-a, --artifactId <String>    Project coordinates; infer archive name (for
                               example 'test')
-b, --boot-version <String>  Spring Boot version (for example '1.2.0.RELEASE')
--build <String>             Build system to use (for example 'maven' or
                               'gradle') (default: maven)
-d, --dependencies <String>  Comma-separated list of dependency identifiers to
                               include in the generated project
--description <String>       Project description
-f, --force                  Force overwrite of existing files
--format <String>            Format of the generated content (for example
                               'build' for a build file, 'project' for a
                               project archive) (default: project)
-g, --groupId <String>       Project coordinates (for example 'org.test')
-j, --java-version <String>  Language level (for example '1.8')
-l, --language <String>      Programming language  (for example 'java')
--list                       List the capabilities of the service. Use it to
                               discover the dependencies and the types that are
                               available
-n, --name <String>          Project name; infer application name
-p, --packaging <String>     Project packaging (for example 'jar')
--package-name <String>      Package name
-t, --type <String>          Project type. Not normally needed if you use --
                               build and/or --format. Check the capabilities of
                               the service (--list) for more details
--target <String>            URL of the service to use (default: https://start.
                               spring.io)
-v, --version <String>       Project version (for example '0.0.1-SNAPSHOT')
-x, --extract                Extract the project archive. Inferred if a
                               location is specified without an extension

examples:

	# 展示springboot 生态圈组件
    To list all the capabilities of the service:
        $ spring init --list
	
	# 创建一个默认的工程
    To creates a default project:
        $ spring init

	# 创建一个web工程zip包
    To create a web my-app.zip:
        $ spring init -d=web my-app.zip

	# 创建一个带有jpa的gradle管理的web应用,放在my-dir目录下
    To create a web/data-jpa gradle project unpacked:
        $ spring init -d=web,jpa --build=gradle my-dir


示例创建SSM项目

spring init -d=web,mybatis,mysql,actuator -a=ssm-demo -g=edu.dongnao.springboot --build=maven ssm-demo

image-20220703165950199

image-20220703165229709

运行groovy脚本
Groovy简介

groovy官网:http://www.groovy-lang.org/

快速入门:https://www.jianshu.com/p/e8dec95c4326

​ Groovy 是 Apache 旗下的一门基于 JVM 平台的动态/敏捷编程语言,在语言的设计上它吸纳了Python、Ruby 和 Smalltalk 语言的优秀特性,语法非常简练和优美,开发效率也非常高(编程语言的开发效率和性能是相互矛盾的,越高级的编程语言性能越差,因为意味着更多底层的封装,不过开发效率会更高,需结合使用场景做取舍)。并且,Groovy 可以与 Java 语言无缝对接,在写 Groovy 的时候如果忘记了语法可以直接按Java的语法继续写,也可以在 Java 中调用 Groovy 脚本,都可以很好的工作,这有效的降低了 Java 开发者学习 Groovy 的成本。Groovy 也并不会替代 Java,而是相辅相成、互补的关系,具体使用哪门语言这取决于要解决的问题和使用的场景。

​ Groovy和Spring与Spring Boot CLI结合在一起,可以在单个Groovy文件部署中快速编写功能强大,高

性能的微服务。

准备groovy脚本
  • 创建app.groovy文件,写入下面内容,类似于java语法

    @RestController
    class UserController{
    	
    	@Autowired
    	private UserService userservice;
    	
    	@RequestMapping("/")
    	public String getUser(){
    		return "Hello "+userservice.say();
    	}
    
    }
    @Service
    class UserService{
    	
    	public String say(){
    		return " CLI World";
    	}
    		
    }
    
  • 运行app.groovy

    sping run app.groovy
    

    第一运行需要下载依赖项非常慢,第二次运行就很快了。

    image-20220703170543730

  • 访问验证

    image-20220703170609339

  • 工程目录组织

    Spring Boot会自动在/config目录中搜索application.yml或application.properties

    ├── app 
    	├── app.groovy 
    	├── config 
    		├── application.yml ...
    

    根据上节课学习的内容还可以在工作目录根目放置配置文件

    ├── app 
    	├── example.groovy 
    	├── example.yml ...
    

    还可以在groovy脚本中通过@Grab注解在类中,来引用依赖和导入包。例如:

    引入actuator健康监测,用@Grab

    @Grab("spring-boot-starter-actuator")
    
    @RestController class ExampleRestController{ 
    	//... 
    }
    

手写SpringBoot实战

SpringBoot基本的思路

设计一个SpringBoot要做些什么

  1. TomcatStart 启动Tomcat,依赖、配置、启动
  2. Servlet DistpatchServlet ,依赖、配置、启动

手写SpringBoot

  1. 创建一个Maven项目ruby-boot,选择quik-start骨架,jkd版本1.8

  2. 导入需要的jar包依赖

    • SpringFramework
    • tomcat
    <!--SpringFramework-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    
    <!-- tomcat-->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>8.5.16</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-jasper</artifactId>
      <version>8.5.16</version>
    </dependency>
    
  3. 创建TomcatStart启动类

    public class TomcatStart {
    
        public static void start(){
            try {
                //创建Tomcat容器,并配置端口
                Tomcat tomcat = new Tomcat();
                tomcat.setPort(8081);
    
                //配置项目信息,创建StandardContext
                StandardContext context = (StandardContext) tomcat
                        .addWebapp("/",new File("src/main").getAbsolutePath());
                context.setReloadable(false);
                //构建webapp
                WebResourceRoot resourceRoot = new StandardRoot(context);
                //获取class文件的读取位置
                File classFile = new File("target/classes");
                resourceRoot.addPreResources(
                        new DirResourceSet(resourceRoot,"/WEB-INF/classes",
                                classFile.getAbsolutePath(),"/"));
    
                //启动
                tomcat.start();
                tomcat.getServer().await();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            start();
        }
    }
    
  4. 实现WebApplicationInitializer,创建父子容器的类

    DispatchServletInitializer

    public class DispatchServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
            implements WebApplicationInitializer {
        /**
         * Spring root IOC容器
         * @return
         */
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[]{RootConfig.class};
        }
    
        /**
         * spring web ioc 容器,子容器
         * @return
         */
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{ServletConfig.class};
        }
    
        /**
         *Spring MVC 访问根路径
         * @return
         */
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    }
    

    RootConfig

    /**
     * Spring root IOC容器
     */
    @ComponentScan(value = "com.fengb.rubyboot"
            ,excludeFilters={@ComponentScan.Filter(type= FilterType.ANNOTATION,classes = {Controller.class})})
    public class RootConfig {
    }
    

    ServletConfig

    /**
     * SpringMVC 容器
     */
    @Configuration
    @ComponentScan(value = "com.fengb.rubyboot.controller",
            includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})},
    useDefaultFilters = false)
    @EnableWebMvc
    public class ServletConfig implements WebMvcConfigurer {
        /**
         *静态资源访问
         * @param configurer
         */
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    
        /**
         * 置Spring MVC 视图解析器
         * @param registry
         */
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            registry.jsp("/WEB-INF/",".jsp");
        }
    }
    
  5. 准备注解

    RubyBootApplication

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RubyBootApplication {
    }
    
  6. 准备启动类 RubyApplication

    public class RubyApplication {
    
        public static void run(Class<?> cl){
            RubyBootApplication annotation = cl.getAnnotation(RubyBootApplication.class);
            if(annotation != null){
                TomcatStart.start();
            }
        }
    }
    
  7. 准备对外入口 RubyBootDemoApplication

    @RubyBootApplication
    public class RubyBootDemoApplication {
        public static void main(String[] args) {
            RubyApplication.run(RubyBootDemoApplication.class);
            System.out.println("RubyBootApplication服务启动了");
        }
    }
    
  8. 编写测试类

    @RestController
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @RequestMapping("/getUser")
        public String getUser(){
            return "RubyBoot : "+userService.getUsre();
        }
    }
    
    @Service
    public class UserService {
    
        public String getUsre(){
            User user = new User();
            user.setName("ruby boot");
            user.setAge(19);
            return user.toString();
        }
    }
    
    public class User {
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
  9. 启动,查看控制台日志,如下启动正常,端口8081

    Connected to the target VM, address: '127.0.0.1:51201', transport: 'socket'
    七月 03, 2022 11:47:38 下午 org.apache.catalina.core.StandardContext setPath
    警告: A context path must either be an empty string or start with a '/' and do not end with a '/'. The path [/] does not meet these criteria and has been changed to []
    七月 03, 2022 11:47:39 下午 org.apache.coyote.AbstractProtocol init
    信息: Initializing ProtocolHandler ["http-nio-8081"]
    七月 03, 2022 11:47:39 下午 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
    信息: Using a shared selector for servlet write/read
    七月 03, 2022 11:47:39 下午 org.apache.catalina.core.StandardService startInternal
    信息: Starting service [Tomcat]
    七月 03, 2022 11:47:39 下午 org.apache.catalina.core.StandardEngine startInternal
    信息: Starting Servlet Engine: Apache Tomcat/8.5.16
    七月 03, 2022 11:47:39 下午 org.apache.catalina.startup.ContextConfig getDefaultWebXmlFragment
    信息: No global web.xml found
    七月 03, 2022 11:47:44 下午 org.apache.catalina.core.ApplicationContext log
    信息: 1 Spring WebApplicationInitializers detected on classpath
    七月 03, 2022 11:47:45 下午 org.apache.jasper.servlet.TldScanner scanJars
    信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
    七月 03, 2022 11:47:45 下午 org.apache.catalina.core.ApplicationContext log
    信息: Initializing Spring root WebApplicationContext
    七月 03, 2022 11:47:45 下午 org.springframework.web.context.ContextLoader initWebApplicationContext
    信息: Root WebApplicationContext: initialization started
    七月 03, 2022 11:47:46 下午 org.springframework.web.context.ContextLoader initWebApplicationContext
    信息: Root WebApplicationContext initialized in 942 ms
    七月 03, 2022 11:47:46 下午 org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
    警告: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [622] milliseconds.
    七月 03, 2022 11:47:46 下午 org.apache.catalina.core.ApplicationContext log
    信息: Initializing Spring DispatcherServlet 'dispatcher'
    七月 03, 2022 11:47:46 下午 org.springframework.web.servlet.FrameworkServlet initServletBean
    信息: Initializing Servlet 'dispatcher'
    七月 03, 2022 11:47:46 下午 org.springframework.web.servlet.FrameworkServlet initServletBean
    信息: Completed initialization in 72 ms
    七月 03, 2022 11:47:46 下午 org.apache.coyote.AbstractProtocol start
    信息: Starting ProtocolHandler ["http-nio-8081"]
    
  10. 访问:http://localhost:8081/getUser

    页面返回:

    RubyBoot : User{name='ruby boot', age=19}
    

    image-20220703235038944

以上就是手写的SpringBoot,实现基本功能

.web.servlet.FrameworkServlet initServletBean
信息: Initializing Servlet ‘dispatcher’
七月 03, 2022 11:47:46 下午 org.springframework.web.servlet.FrameworkServlet initServletBean
信息: Completed initialization in 72 ms
七月 03, 2022 11:47:46 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler [“http-nio-8081”]


10. 访问:http://localhost:8081/getUser

 页面返回:

 ```properties
 RubyBoot : User{name='ruby boot', age=19}
 ```

 [外链图片转存中...(img-1u9qnPdB-1748236831668)]

以上就是手写的SpringBoot,实现基本功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值