SpringBoot应用——项目搭建指北
作者:互联网
文章目录
一、工程结构规范
1、数据持久层:底层 MySQL 、 Oracle 、 Hbase 等进行数据交互 2、各个层级有自己的数据封装实体类:DO、DTO、VO、query等等 3、dao层引入数据库信息,除了实体类,还包含mapper 4、从jar引入角度看 manager引入dao,service引入manager web(controller层)引入service 对外接口api层引入service,但是建议不引入controller层 5、从调用关系看,就是如图的调用层级关系 6、common通用包 不需要引入dao层,里面包含的是各种工具、枚举或常量,直接为manager引用 |
---|
二、创建springBoot项目
1、Idea中,我们可以直接使用Maven创建
2、在大的外层模块中继续创建各种子模块
3、根据工程结构规范,进行包引入
<!--这是service层,由于没有manager,则需要直接引入common和dao-->
<dependencies>
<dependency>
<groupId>com.rj</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.rj</groupId>
<artifactId>dao</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<!--这是api层-->
<!--可以将项目中其他模块jar包引入,版本号与当前模块的parent一致-->
<dependency>
<groupId>com.rj</groupId>
<artifactId>service</artifactId>
<version>${project.version}</version>
</dependency>
4、引入springBoot依赖,进行版本控制
- 1、版本的控制必须在父模块的pom文件中控制,即
SpringBootTest
模块
<!--版本号控制-->
<properties>
<spring-boot-parent.version>2.0.1.RELEASE</spring-boot-parent.version>
<spring-boot-mybatis.version>2.0.0</spring-boot-mybatis.version>
<mybatis-plus-boot-starter>3.4.2</mybatis-plus-boot-starter>
<mybatis-plus-generator>3.4.0</mybatis-plus-generator>
<hutool-all.version>5.6.6</hutool-all.version>
<spring-boot-druid.version>1.1.10</spring-boot-druid.version>
<mysql.version>5.1.29</mysql.version>
<lombok.version>1.16.10</lombok.version>
<junit4.version>4.12</junit4.version>
<java.version>1.8</java.version>
<spring-boot-maven-plugin.version>2.2.5.RELEASE</spring-boot-maven-plugin.version>
</properties>
<!--这个是版本控制管理,不会引入jar包,而只是声明名称和版本,具体的引用在子模块-->
<dependencyManagement>
<dependencies>
<!--引入需要的springBoot组件,需要指定版本号${version}-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-parent.version}</version>
</dependency>
<!--log日志,内置的是logback-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>${spring-boot-parent.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${spring-boot-mybatis.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-boot-starter}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>${spring-boot-parent.version}</version>
</dependency>
<!--自动生成domain/dao层的框架,可以不需要-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus-generator}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot-parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${spring-boot-druid.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool-all.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit4.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
使用
dependencyManagement
和直接使用dependencies
的最大区别,在于,前者只是声明要使用什么依赖以及对应版本号,但不会真正导入依赖,即使飘红也没关系;后者会真正导入依赖。
所以,使用前者,我们就可以在子模块中根据子模块的实际情况进行实际的jar包引入;而后者,则会在各个子模块中都会全部引入,这是很不合规范的
- 2、在子模块中根据实际情况真实引入jar包依赖
<!--这是api层,我们只需要引入spring-boot-starter-web的jar包-->
<dependencies>
<!--子模块根据需要实际引入jar包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
同理,可以在dao层引入数据库、mybatis、mybatis-plus等对应的jar包 在common可以引入日志依赖,根据传递依赖原则,在顶层的api层都有依赖进来。 |
---|
5、配置文件
在web或api层的resource目录中配置yml文件,注意命名规范:application.yml
#dataSource
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/mydb3?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
druid:
initial-size: 3
min-idle: 3
max-active: 10
max-wait: 60000
filter:
stat:
log-slow-sql: true
slow-sql-millis: 1
#环境:env就是pom中的环境选择标签
profiles:
active: ${env}
#tomcat端口号
server:
port: 8089
servlet:
context-path: /rj
tomcat:
uri-encoding: utf-8
#mybatis
mybatis-plus:
type-aliases-package: com.rj.domain
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:com/rj/*/mapper/*.xml
#log日志配置
logging:
config: classpath:logback.xml
同级位置
配置对应的开发或者生成环境配置文件,注意明明规范application-dev.yml
和application-pro.yml
并在对应的pom文件中配置环境选择
<!-- 开发环境,默认激活 -->
<profiles>
<profile>
<!--id要和env中的一致-->
<id>dev</id>
<properties>
<!--这个只是针对的文件后缀,即application-后面的-->
<env>dev</env>
</properties>
<!--默认环境 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!-- 生产环境 -->
<profile>
<id>pro</id>
<properties>
<env>pro</env>
</properties>
</profile>
</profiles>
同级位置
引入我们的日志配置logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志路径 -->
<property name="log_dir" value="/export/Logs/iceStatistic"/>
<!-- 控制台 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern><!--%black(控制台-)--> %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{10}) - %cyan(%msg%n)
</pattern>
</encoder>
</appender>
<!-- debug日志 -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log_dir}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log_dir}/debug-%d{yyyy-MM-dd-HH}.log</fileNamePattern>
<maxHistory>48</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %thread %X{invokeNo} %logger{40} %msg%n</pattern>
</encoder>
</appender>
<!-- info日志 -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log_dir}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log_dir}/info-%d{yyyy-MM-dd-HH}.log</fileNamePattern>
<maxHistory>72</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %thread %X{invokeNo} %logger{40} %msg%n</pattern>
</encoder>
</appender>
<!-- error日志 -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log_dir}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log_dir}/error-%d{yyyy-MM-dd-HH}.log</fileNamePattern>
<maxHistory>72</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %thread %X{invokeNo} %logger{40} %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<logger name="DEBUG_LOG" level="debug" additivity="false">
<appender-ref ref="debug"/>
</logger>
<logger name="INFO_LOG" level="info" additivity="false">
<appender-ref ref="info"/>
</logger>
<logger name="ERROR_LOG" level="error" additivity="false">
<appender-ref ref="error"/>
</logger>
<logger name="com.jd.flight" level="debug" additivity="false">
<appender-ref ref="stdout"/>
<appender-ref ref="debug"/>
</logger>
<root level="info">
<appender-ref ref="stdout"/>
<appender-ref ref="info"/>
<appender-ref ref="error"/>
</root>
</configuration>
6、springBoot启动类
在web或api层的java/com/rj/
下创建启动类
@SpringBootApplication
@MapperScan("com.rj.*.mapper")
public class AppStart {
public static void main(String[] args) {
SpringApplication.run(AppStart.class,args);
}
}
springBootApplication是自动装配,MapperScan是对mapper文件的扫描
由于springBoot内置tomcat,直接启动这个类,就可以将项目起来
springBoot的测试类
@SpringBootTest(classes = AppStart.class)
@RunWith(SpringRunner.class)
@Slf4j
public class StudentTest {
//这个是在yml文件中配置的,虽然yml是冒号分隔,但是这里还是需要使用“.”来调用
@Value("${vipuser.name}")
private String name;
@Test
public void testStudent() {
log.error("name = {}", name);
}
}
7、在web或api层,pom中需要配置打包build
<!--build-->
<!-- Package as an executable jar -->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<!--可以访问的资源文件路径-->
<includes>
<include>application.yml</include>
<include>application-${env}.yml</include>
<include>*.txt</include>
<include>**/*.xml</include>
<include>**/messages*.properties</include>
<include>**/*.csv</include>
<include>**/*.zip</include>
<include>**/*.ftl</include>
<include>*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot-maven-plugin.version}</version>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
spring-boot-maven-plugin.version
和java.version
版本也可以在父pom中控制
8、排包
这项操作非常重要,由于包冲突,导致项目启动失败,这里推荐使用插件
Maven Helper
进行包冲突排除,建议将低版本的jar包排除掉
9、mybatis自动生成工具类
(选用) 根据数据库表自动生成domain、mapper、mapper.xml、service和controller
//需要引入`mybatis-plus-generator`和`spring-boot-starter-freemarker`
package codegenerate;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
/**
* 根据数据库表自动生成domain/mapper/service/controller
*/
@RunWith(JUnit4.class)
public class CodeGenerator {
/**
* 运行测试生成
*/
@Test
public void doGenerator() {
generator("user", "student");
}
/**
* 自动生成的方法
* @param nodeName 业务模块的名称,比如用户user、商品good...,同名会追加类
* @param tables 表名,可多个,建议单个生成
*/
@SuppressWarnings("all")
private static void generator(String nodeName, String... tables) {
final String fNodeName = StringUtils.isEmpty(nodeName) ? "test" : nodeName;
//代码生成器
AutoGenerator mpg = new AutoGenerator();
//局配置
GlobalConfig gc = new GlobalConfig();
//获取工程的绝对路径
final String parentPath = "D:\\Java\\ProjectJ\\springBootTest";
gc.setAuthor("rj");
gc.setOpen(false);
gc.setSwagger2(false);
mpg.setGlobalConfig(gc);
//数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mydb3?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
mpg.setDataSource(dsc);
//包配置: src\main\java\com\rj\domain
PackageConfig pc = new PackageConfig();
//生成文件夹
Map<String, String> configPathInfo = new HashMap(8) {
{
put(ConstVal.XML_PATH, parentPath + "\\dao\\src\\main\\java\\com\\rj\\"+fNodeName+"\\mapper");
put(ConstVal.MAPPER_PATH, parentPath + "\\dao\\src\\main\\java\\com\\rj\\"+fNodeName+"\\mapper");
put(ConstVal.ENTITY_PATH, parentPath + "\\dao\\src\\main\\java\\com\\rj\\domain\\"+fNodeName+"\\entity");
put(ConstVal.SERVICE_PATH, parentPath + "\\service\\src\\main\\java\\com\\rj\\"+fNodeName+"\\service");
put(ConstVal.SERVICE_IMPL_PATH, parentPath + "\\service\\src\\main\\java\\com\\rj\\"+fNodeName+"\\service\\impl");
put(ConstVal.CONTROLLER_PATH, parentPath + "\\api\\src\\main\\java\\com\\rj\\"+fNodeName+"\\controller");
}
};
//生成对应的类
pc.setPathInfo(configPathInfo);
pc.setParent("com.rj");
pc.setXml(fNodeName+".mapper");
pc.setMapper(fNodeName+".mapper");
pc.setEntity("domain."+fNodeName+".entity");
pc.setService(fNodeName+".service");
pc.setServiceImpl(fNodeName+".service.impl");
pc.setController(fNodeName+".controller");
mpg.setPackageInfo(pc);
//策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setInclude(tables);
//表前缀,根据具体情况修改
strategy.setTablePrefix("");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
10、关于@Configuration
和@Bean
//@Configuration 创建自己的线程池,并交给spring管理
@Configuration
public class MyThreadExecutorConfig {
/**
* 核心线程数
*/
private static final int CORE_POOL_SIZE = 5;
/**
* 最大线程数
*/
private static final int MAX_POOL_SIZE = 8;
/**
* 最大等待时间
*/
private static final long KEE_PALIVE = 60L;
/**
* 线程队列
*/
private static final int QUEUE_SIZE = 5;
/**
* 方法上打上@Bean注解,并指定方法名id,就可以使用方法名直接调用
*/
@Bean("threadpool")
public ThreadPoolExecutor getExecutor() {
return new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEE_PALIVE,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(QUEUE_SIZE),
new ThreadPoolExecutor.AbortPolicy());
}
}
//我们也可以使用yml配置文件注入参数
/**
* 核心线程数
*/
@Value("${mythread.core.size}")
private int CORE_POOL_SIZE;
//调用线程池:这里使用的是@Autowired,所以会根据类名去找,而与我们指定的bean名称id无关
//如果我们使用@Resource,则必须将这个类的名字与我们指定的@Bean的名称id一致
@Autowired
private ThreadPoolExecutor threadpool1324251;
@Resource
private ThreadPoolExecutor threadpool;
//这样就可以直接使用线程池了
标签:指北,SpringBoot,spring,boot,version,log,com,rj,搭建 来源: https://blog.csdn.net/qq_45337431/article/details/117616243