Tio Boot 与 Spring Boot Starter 的集成

背景

在以前的整合模式中,我们通过 spring-boot-starter-web 将 Spring Boot 的 Controller 与 Tio Boot 的 Service 相整合。这种方法虽然能够工作,但却失去了 Tio Boot 在处理请求时的异步和非阻塞特性。

新的整合方式

为了充分利用 Tio Boot 的异步和非阻塞优势,我们提出了一个新的整合方法:仅仅整合 spring-boot-starter,并使用 Tio Boot 的 Controller 来处理请求。

Maven 配置(pom.xml)

首先,我们配置 Maven 项目的 pom.xml 文件。以下是主要的配置部分:

  1. Java 和 Spring Boot 版本设置:确保使用适合的 Java 版本和 Spring Boot 版本。
  2. 依赖项:除了标准的 Spring Boot Starter 依赖,还包括 tio-boot 和其他必要的库,如 Lombok、数据库连接池(Druid)和数据库驱动(MySQL)。
  3. 构建配置:使用 spring-boot-maven-plugin 来支持热启动和其他 Spring Boot 特性。

    <properties>
      <java.version>1.8</java.version>
      <maven.compiler.source>${java.version}</maven.compiler.source>
      <maven.compiler.target>${java.version}</maven.compiler.target>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <spring-boot.version>2.5.6</spring-boot.version>
      <main.class>com.litongjava.spring.boot.tio.boot.demo01.Applicaton</main.class>
    </properties>
    
    <dependencies>
      <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter</artifactId>
      </dependency>
    
      <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <scope>provided</scope>
      </dependency>
    
      <!-- SpringBoot集成Test -->
      <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
     <scope>test</scope>
      </dependency>
    
      <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <scope>test</scope>
      </dependency>
    
      <dependency>
     <groupId>com.litongjava</groupId>
     <artifactId>tio-boot</artifactId>
     <version>1.3.3</version>
      </dependency>
    
      <dependency>
     <groupId>com.litongjava</groupId>
     <artifactId>jfinal-plugins</artifactId>
     <version>1.0.3</version>
      </dependency>
      <!-- 连接池 -->
      <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid</artifactId>
     <version>1.1.10</version>
      </dependency>
      <!-- 数据库驱动 -->
      <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
      </dependency>
    
    </dependencies>
    
    <build>
      <plugins>
     <!-- Spring Boot -->
     <plugin>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-maven-plugin</artifactId>
       <version>${spring-boot.version}</version>
       <configuration>
         <includeSystemScope>true</includeSystemScope>
         <!--使该插件支持热启动 -->
         <fork>true</fork>
         <mainClass>${main.class}</mainClass>
         <excludeGroupIds>org.projectlombok</excludeGroupIds>
       </configuration>
       <!-- 设置执行目标 -->
       <executions>
         <execution>
           <goals>
             <goal>repackage</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
      </plugins>
    </build>
    
    <dependencyManagement>
      <dependencies>
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-dependencies</artifactId>
       <version>${spring-boot.version}</version>
       <type>pom</type>
       <scope>import</scope>
     </dependency>
      </dependencies>
    </dependencyManagement>

启动类(Application)

接下来,定义 Spring Boot 应用的启动类:

package com.litongjava.spring.boot.tio.boot.demo01;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.litongjava.jfinal.aop.annotation.AComponentScan;

@SpringBootApplication
@AComponentScan
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

这个类标记为 Spring Boot 应用,并启动整个应用。

配置类(Configuration)

配置类负责整合 Tio Boot:

package com.litongjava.spring.boot.tio.boot.demo01.config;

import org.springframework.boot.ApplicationArguments;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.litongjava.spring.boot.tio.boot.demo01.Applicaton;
import com.litongjava.tio.boot.TioApplication;
import com.litongjava.tio.boot.context.Context;

@Configuration
public class TioApplicationConfig {

  @Bean
  public Context myBean(ApplicationArguments args) {
    String[] sourceArgs = args.getSourceArgs();
    return TioApplication.run(Applicaton.class, sourceArgs);
  }
}

配置类负责整合 ActiveRecordPlugin

package com.litongjava.spring.boot.tio.boot.demo01.config;

import com.litongjava.jfinal.aop.Aop;
import com.litongjava.jfinal.aop.annotation.ABean;
import com.litongjava.jfinal.aop.annotation.AConfiguration;
import com.litongjava.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.litongjava.jfinal.plugin.activerecord.OrderedFieldContainerFactory;
import com.litongjava.jfinal.plugin.druid.DruidPlugin;

@AConfiguration
public class ActiveRecordPluginConfig {
  @ABean(priority = 10)
  public DruidPlugin druidPlugin() {
    String jdbcUrl = "jdbc:mysql://192.168.3.9:3306/mybatis_plus_study";
    String jdbcUser = "root";
    String jdbcPswd = "robot_123456#";

    DruidPlugin druidPlugin = new DruidPlugin(jdbcUrl, jdbcUser, jdbcPswd);
    druidPlugin.start();
    return druidPlugin;
  }

  @ABean
  public ActiveRecordPlugin activeRecordPlugin() {
    DruidPlugin druidPlugin = Aop.get(DruidPlugin.class);
    ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
    arp.setContainerFactory(new OrderedFieldContainerFactory());
    arp.start();
    return arp;
  }
}

Service和Controller

定义 Service 接口和实现,以及相应的 Controller 来处理请求。例如,UserController 使用 Tio Boot 的注解 @RequestPath 来定义路由。
service

package com.litongjava.spring.boot.tio.boot.demo01.service;

import java.util.List;

import com.litongjava.jfinal.plugin.activerecord.Record;

public interface UserService {
  List<Record> listAll();
}
package com.litongjava.spring.boot.tio.boot.demo01.service;

import java.util.List;

import com.litongjava.jfinal.aop.annotation.AService;
import com.litongjava.jfinal.plugin.activerecord.Db;
import com.litongjava.jfinal.plugin.activerecord.Record;

@AService
public class UserServiceImpl implements UserService {

  public List<Record> listAll() {
    return Db.findAll("user");
  }
}

controller

package com.litongjava.spring.boot.tio.boot.demo01.controller;

import java.util.List;

import com.litongjava.jfinal.aop.Aop;
import com.litongjava.jfinal.plugin.activerecord.Record;
import com.litongjava.spring.boot.tio.boot.demo01.service.UserService;
import com.litongjava.tio.http.server.annotation.RequestPath;

@RequestPath("/user")
public class UserController {

  public List<Record> listAll() {
    return Aop.get(UserService.class).listAll();
  }
}

启动测试

启动访问http://localhost/user/listAll

单独测试Service

我们可以编写单元测试来测试 Service 层的逻辑。

package com.litongjava.spring.boot.tio.boot.demo01.services;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.litongjava.jfinal.aop.Aop;
import com.litongjava.jfinal.plugin.activerecord.Record;
import com.litongjava.spring.boot.tio.boot.demo01.Applicaton;
import com.litongjava.spring.boot.tio.boot.demo01.service.UserService;
import com.litongjava.tio.boot.TioApplication;

public class UserServiceTest {

  @Before
  public void before() {
    List<String> list = new ArrayList<String>();
    list.add("--tio.noServer=true");
    String[] args = list.toArray(new String[] {});
    TioApplication.run(Applicaton.class, args);
  }

  @Test
  public void test() {
    UserService userService = Aop.get(UserService.class);
    List<Record> listAll = userService.listAll();
    System.out.println(listAll);
  }
}

李通
215 声望0 粉丝