从spring网站创建
首先到http://start.spring.io/ 创建项目,自定义添加需要的依赖,下载后使用IDEA打开
项目结构:
Customer
package com.mythsky.springbootdemo.domain; public class Customer { private int id; private String name; private String contact; private String telephone; private String email; private String remark; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContact() { return contact; } public void setContact(String contact) { this.contact = contact; } public String getTelephone() { return telephone; } public void setTelephone(String telephone) { this.telephone = telephone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } }
CustomerDao
package com.mythsky.springbootdemo.dao; import com.mythsky.springbootdemo.domain.Customer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; @Component public class CustomerDao { @Autowired JdbcTemplate jdbcTemplate; public Customer getCustomer(int id){ return jdbcTemplate.queryForObject("select * from customer where id="+id,new BeanPropertyRowMapper<>(Customer.class)); } }
CustomerController
package com.mythsky.springbootdemo.contorller; import com.mythsky.springbootdemo.dao.CustomerDao; import com.mythsky.springbootdemo.domain.Customer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class CustomerController { @Autowired private CustomerDao customerDao; @RequestMapping("/customer") public String getCustomer(){ String name="Hello"; Customer customer=customerDao.getCustomer(1); name=customer.getName(); return name; } }
配置数据库
输入命令:mvn spring-boot:run
数据库:
打开浏览器:http://localhost:8080/customer 即可看到结果。
在IDEA中创建
代码结构
修改启动代码
@SpringBootApplication @RestController public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @RequestMapping("/") String home(){ return "Hello"; } }
打开浏览器:http://localhost:8080 即可看到结果。
打包发布
在IDEA作下角选择
这样就在项目的target目录中生成了jar文件,切换到目录中运行
java -jar .demo-0.0.1-SNAPSHOT.jar
最后打开浏览器即可查看。
这里可以查看spring-boot预定义的配置参数:
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
实现RESTful API
@RestController public class HelloController { @GetMapping("/hello") public String index(){ return "Hello World!"; } }
单元测试
import static org.hamcrest.core.IsEqual.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) @SpringBootTest @WebAppConfiguration public class BootdemoApplicationTests { private MockMvc mvc; @Before public void setUp() { mvc=MockMvcBuilders.standaloneSetup(new HelloController()).build(); } @Test public void hello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("Hello World!"))); } }
先看看测试不通过的情况
测试通过
自定义参数
在application.properties中设置参数
student.name=tom
student.age=18
通过@Value注解来加载
@Component public class Student { @Value("${student.name}") private String name; @Value("${student.age}") 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; } }
测试
@Autowired private Student student; @Test public void student(){ Assert.assertEquals("判断名字是否相同","tom",student.getName()); }
参数引用
log
Custom Log Configuration
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <property name="LOG_HOME" value="/test/log" /> <property name="logback.logdir" value="/test/log"/> <property name="logback.appname" value="app"/> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!--输出到控制台 ConsoleAppender--> <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> <!--展示格式 layout--> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern> <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern> </pattern> </layout> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高, 所以我们使用下面的策略,可以避免输出 Error 的日志--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!--过滤 Error--> <level>ERROR</level> <!--匹配到就禁止--> <onMatch>DENY</onMatch> <!--没有匹配到就允许--> <onMismatch>ACCEPT</onMismatch> </filter> <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则 如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天 的日志改名为今天的日期。即,<File> 的日志都是当天的。 --> <File>${logback.logdir}/info.${logback.appname}.log</File> <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间--> <FileNamePattern>${logback.logdir}/info.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern> <!--只保留最近90天的日志--> <maxHistory>90</maxHistory> <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志--> <!--<totalSizeCap>1GB</totalSizeCap>--> </rollingPolicy> <!--日志输出编码格式化--> <encoder> <charset>UTF-8</charset> <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern> </encoder> </appender> <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>Error</level> </filter> <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则 如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天 的日志改名为今天的日期。即,<File> 的日志都是当天的。 --> <File>${logback.logdir}/error.${logback.appname}.log</File> <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间--> <FileNamePattern>${logback.logdir}/error.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern> <!--只保留最近90天的日志--> <maxHistory>90</maxHistory> <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志--> <!--<totalSizeCap>1GB</totalSizeCap>--> </rollingPolicy> <!--日志输出编码格式化--> <encoder> <charset>UTF-8</charset> <pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern> </encoder> </appender> <!--myibatis log configure--> <logger name="com.apache.ibatis" level="TRACE"/> <logger name="java.sql.Connection" level="DEBUG"/> <logger name="java.sql.Statement" level="DEBUG"/> <logger name="java.sql.PreparedStatement" level="DEBUG"/> <!-- 日志输出级别 --> <!--<root level="INFO">--> <!--<appender-ref ref="STDOUT" />--> <!--<appender-ref ref="FILE" />--> <!--</root>--> </configuration>
The logback manual
可以在layout中添加颜色及其他效果
https://logback.qos.ch/manual/layouts.html#coloring
配置文件
application.yml
spring: profiles: active: test --- spring.profiles: dev spring: application: name: consumer-dev sleuth: sampler: probability: 1 zipkin: base-url: http://172.20.102.150:9411 server: port: 9000 service: username: user password: pwd123 eureka: client: service-url: defaultZone: http://${service.username}:${service.password}@172.20.102.149:8090/eureka/,http://${service.username}:${service.password}@172.20.102.150:8090/eureka/,http://${service.username}:${service.password}@172.20.102.151:8090/eureka/ --- spring.profiles: test spring: application: name: consumer-test sleuth: sampler: probability: 1 zipkin: base-url: http://172.20.102.150:9411 server: port: 9000 service: username: user password: pwd123 eureka: client: service-url: defaultZone: http://${service.username}:${service.password}@172.20.102.149:8090/eureka/,http://${service.username}:${service.password}@172.20.102.150:8090/eureka/,http://${service.username}:${service.password}@172.20.102.151:8090/eureka/ --- spring.profiles: prod spring: application: name: consumer-prod sleuth: sampler: probability: 1 zipkin: base-url: http://172.20.102.150:9411 server: port: 9000 service: username: user password: pwd123 eureka: client: service-url: defaultZone: http://${service.username}:${service.password}@172.20.102.149:8090/eureka/,http://${service.username}:${service.password}@172.20.102.150:8090/eureka/,http://${service.username}:${service.password}@172.20.102.151:8090/eureka/
可以在一个文件中配置多个环境,也可以在多个文件中配置
application-dev.yml application-test.yml
application.properties
#服务名称 spring.application.name=ribbon-consumer #服务端口 server.port=9000 #连接注册中心用户名 service.username=user #连接注册中心密码 service.password=pwd123 #注册中心地址,集群地址使用逗号分隔 eureka.client.service-url.defaultZone=http://${service.username}:${service.password}@172.20.102.149:8090/eureka/,http://${service.username}:${service.password}@172.20.102.150:8090/eureka/,http://${service.username}:${service.password}@172.20.102.151:8090/eureka/ #追踪发送zipkin频率,单位为百分比,1为百分百 spring.sleuth.sampler.probability=1 #zipkin地址 spring.zipkin.base-url=http://172.20.102.150:9411
同样可以使用多环境 application-dev.properties