SpringBoot应用——项目搭建指北
2021/6/6 10:22:55
本文主要是介绍SpringBoot应用——项目搭建指北,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 一、工程结构规范
- 二、创建springBoot项目
- 1、Idea中,我们可以直接使用Maven创建
- 2、在大的外层模块中继续创建各种子模块
- 3、根据工程结构规范,进行包引入
- 4、引入springBoot依赖,进行版本控制
- 5、配置文件
- 6、springBoot启动类
- 7、在web或api层,pom中需要配置打包build
- 8、排包
- 9、mybatis自动生成工具类
- 10、关于`@Configuration`和`@Bean`
一、工程结构规范
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应用——项目搭建指北的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南