跳至主要內容

SpringBoot初体验

soulballad微服务SpringCloud NetfilxSpringCloud约 1052 字大约 4 分钟

SpringBoot初体验

http://projects.spring.io/spring-boot/

1570074994840

基本概念

应用分为两个方面:功能性、非功能性

  • 功能性:系统所设计的业务范畴
  • 非功能性:安全、性能、监控、数据指标(CPU利用率、网卡使用率)

production-ready 就是非功能性范畴!

Spring Boot 规约大于配置,大多数组件,不需要自行配置,而是自动组装!简化开发,大多数情况,使用默认即可!

springboot 特性

1570075074898

springboot 技术体系

1570075347792

springboot 基础应用

  1. 项目结构

    1570078532116

  2. 使用 webflux,webflux 可以兼容 spring mvc

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    
  3. 实体类

    public class User {
    
        private Long id;
        private String name;
    
    	// get&set
    }
    
  4. 仓储

    @Repository
    public class UserRepository {
    
        private final ConcurrentMap<Long, User> userMap = new ConcurrentHashMap<>();
    
        private final AtomicLong idGenerator = new AtomicLong();
    
        public Boolean save(User user) {
            // ID 从 1 开始
            long id = idGenerator.incrementAndGet();
            user.setId(id);
            return userMap.put(id, user) == null;
        }
    
        public Collection<User> findAll() {
            return userMap.values();
        }
    }
    
  5. 控制器,使用spring mvc

    @RestController
    public class UserController {
    
        private final UserRepository userRepository;
    
        @Autowired
        public UserController(UserRepository userRepository) {
            this.userRepository = userRepository;
        }
    
        // 保存使用 Spring Web MVC
        @PostMapping("/user/save")
        public User user(@RequestParam String name) {
            User user = new User();
            user.setName(name);
            userRepository.save(user);
            return user;
        }
    }
    
  6. webflux配置,使用 spring webflux

    @Configuration
    public class WebFluxConfiguration {
    
        @Autowired
        @Bean
        public RouterFunction<ServerResponse> findAllUsers(UserRepository userRepository){
            Collection<User> users = userRepository.findAll();
            Flux<User> userFlux = Flux.fromIterable(users);
            return RouterFunctions.route(RequestPredicates.path("/users"),
                    request -> ServerResponse.ok().body(userFlux, User.class));
        }
    }
    
  7. postman 测试

    • spring webmvc

      1570078786521

    • spring webflux

      1570078826673

构建多模块项目

  1. 结构如图所示

    1570086323012

  2. 修改主工程类型 jar -> pom

    <packaging>jar</packaging>
    <packaging>pom</packaging>
    
  3. 新建 web 工程,将遗留代码移动到 web java 目录下

  4. 再从 web 工程,独立出 model 工程

  5. 将 web 工程依赖 model 工程

  6. 重复步骤 3,独立出 persistence

    <dependencies>
        <dependency>
            <groupId>com.gupao</groupId>
            <artifactId>app-persistence</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
    
  7. 再从 persistence 添加 model 的依赖

    <dependencies>
        <dependency>
            <groupId>com.gupao</groupId>
            <artifactId>app-model</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
    
  8. 最终依赖关系 web -> persistence -> model

    <modules>
        <module>app-web</module>
        <module>app-model</module>
        <module>app-persistence</module>
    </modules>
    

构建可执行 jar 或者 war

app-web-1.0.0-SNAPSHOT.jar 中没有主清单属性?

1570088627988

需要一个 Spring Boot(添加在 app-web 项目) 的插件:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

jar 规范里面,有一个 MANIFEST.MF,里面有一个 Main-Class 的属性。API:java.util.jar.Manifest#getAttributes

解压 app-web-0.0.1-SNAPSHOT.jar 可以看到

1570086446808

jar 包启动

java -jar .\app-web-0.0.1-SNAPSHOT.jar

1570086625135

从 jar 切换成 war 打包方式
  1. 修改 <packaging> 成 war

    <packaging>war</packaging>
    

    直接打包出现错误

    1570086789718

  2. 创建 webapp/WEB-INF 目录(相对于src/main

  3. 新建一个空的web.xml

注意 步骤2 和 步骤3 是为了绕过war插件的限制,小马哥笨办法

或者使用

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>

解压 app-web-0.0.1-SNAPSHOT.war 可以看到

1570087009317

war 包启动

java -jar .\app-web-0.0.1-SNAPSHOT.war

1570087381059

启动注意事项
  • BOOT-INF 是 Spring Boot 1.4 开始才有

  • 当使用依赖或者插件时,如果版本是 Milestone的时候,需要增加:

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/snapshot</url>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/milestone</url>
        </pluginRepository>
    </pluginRepositories>
    
  • META-INF/MANIFEST.MF 里面有指定两个属性

    • Main-Class
    • Start-Class
      • 例子:
      • Main-Class: org.springframework.boot.loader.JarLauncher
        Start-Class: com.gupao.app.SpringBootAppApplication
  • 除了 jar 或者 war 启动的方式,还有目录启动方式

    • 目录启动方式可以帮助解决老旧的jar 不支持 Spring Boot 新方式,比如老版本的 MyBatis

      • 如果是 jar 包,解压后,跳转解压目录,并且执行java命令启动,启动类是 org.springframework.boot.loader.JarLauncher

        1570087130229

      • 如果是 war包,解压后,跳转解压目录,并且执行java命令启动类是org.springframework.boot.loader.WarLauncher

        1570087202789

启动多个实例

# --server.port 随机可用端口
java -jar .\app-web-0.0.1-SNAPSHOT.war --server.port=0

1570087642770

1570087730275

1570087761436

查看启动端口

注意控制台:Netty started on port(s): 8080

1570087674259

1570087689170

上次编辑于:
贡献者: soulballad