【转】Spring Boot 构建应用——快速构建 Spring Boot 应用

Spring Boot 简化了 Spring 应用开发,不须要配置就能运行 Spring 应用,Spring Boot 的自动配置是经过 Spring 4.x 的条件注解 @Conditional 来实现的,@Conditional 根据特定条件来控制 bean 的建立行为。Spring Boot 默认会使用内置的 Tomcat,并支持 Spring MVC、RESTful 服务。新建 Spring Boot 项目很简单,IntelliJ IDEA 在 New Project 中选择 Spring Initializr,而后组件选择 Web (集成 Spring MVC 框架) 便可建立成功。Spring Boot 经过 Starter 来提供系统级服务,Spring Boot 已经提供了一系列的 Starter,下表是 Spring Boot 提供的经常使用 Starter:javascript

名称 做用
spring-boot-starter-web Web开发支持,默认使用Tomcat8
spring-boot-starter-aop AOP开发支持,使用AspectJ
spring-boot-starter-test 包含JUnit、Spring Test、Hamcrest、Mockito等测试工具
spring-boot-starter-jdbc Spring JDBC
spring-boot-starter-cache 缓存,支持多种缓存方式,如本地的、Redis、Ehcache等
spring-boot-starter-activemq 消息集成ActiveMQ支持
spring-boot-starter-amqp 消息集成AMQP协议支持,如支持RabbitMQ
spring-boot-starter-web-services webservice支持
spring-boot-starter-websocket websocket支持
spring-boot-starter-jersey REST应用和Jersey支持
spring-boot-starter-freemarker Freemarker模板引擎支持
spring-boot-starter-thymeleaf Thymeleaf模板引擎支持
spring-boot-starter-jta-atomikos 分布式事务支持,使用atomikos
spring-boot-starter-jta-bitronix 一个开源的分布式事务支持
spring-boot-starter-data-jpa JPA方式访问数据库,使用Hibernate做为JPA实现
spring-boot-starter-data-elasticsearch 集成Elasticsearch,默认访问localhost:9200
spring-boot-starter-data-redis 集成Redis,使用JRedis,默认链接localhost:6379
spring-boot-starter-data-mongodb 集成MongoDB,默认访问mongodb://localhost/test
spring-boot-starter-data-neo4j 集成neo4j,默认访问localhost:7474
spring-boot-starter-data-gemfire 集成分布式缓存
spring-boot-starter-data-solr 集成solr搜索平台,默认访问http://localhost:8983/solr
spring-boot-starter-data-cassandra 集成Cassandra,默认访问localhost:7474
spring-boot-starter-data-ldap 集成ldap
spring-boot-devtools 页面和代码的热部署,在修改类或者配置文件的时候自动从新加载Spring Boot应用

1.多环境配置

在 resources 下新建全局配置文件 application.properties、开发环境配置文件 application-dev.properties 和生产环境配置文件 application-prod.properties,application.properties 配置以下:css

#使用开发环境 spring.profiles.active=dev #自定义 example.str=hello

 

 

其中的 str 能够经过 @Value 获取值:html

@Value("${example.str}") private String str;

 

生产环境配置文件 application-dev.properties 配置以下:java

server.port=8081
  • 1

2.Spring Boot配置类

Spring Boot 经过 @Configuration 注册 bean,例如:web

@Configuration public class HelloConfig { @Bean public MessageConverter messageConverter() { return new Jackson2JsonMessageConverter(); } }

 

3.开发Spring MVC应用

使用 Spring Boot 能够高效的开发 Spring MVC 应用,须要注意的是,MVC 和三层架构 (展示层 + 应用层 (Service层) + 数据访问层 (Dao层) ) 是两个不一样的概念,MVC 只存在三层架构的展示层,M 是数据模型,V 是视图页面,C 是控制器。MVC 和核心思想是业务数据抽取与业务数据呈现相分离。redis

Spring Boot经常使用注解 释义
@RestController Spring4以后新加的注解,等同于@ResponseBody+@Controller
@RequestMapping url映射,value能够为数组,例如{“/hello”, “/hi”}
@GetMapping GET类型的url映射,还有@PostMapping、@PutMapping、@DeleteMapping
@PathVariable 获取url中的数据
@RequestParam 获取请求参数的值,required属性表示是否必传,defaultValue属性表示默认值
@RequestBody 用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,好比application/json或application/xml等。

新建 HelloController:spring

@RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello, Spring Boot!"; } }

 

运行项目(mvn spring-boot:run 命令),浏览器访问 http://localhost:8081/hello,便可看到输出结果 “Hello, Spring Boot!”。Spring Boot其余经常使用注解以下:mongodb

Spring Boot经常使用注解 释义
@Component 通用注解,会被注册为bean组件、基于它的还有@Repository、@Service、@Controller
@Autowired 标注在构造方法、类的任何方法上,实现自动装配
@Resource 默认按名称装配,当找不到与名称匹配的bean才会按类型装配
@Lazy(true) 表示延迟初始化
@Import 导入配置类,并支持导入普通的java类,并将其声明成一个bean
@Transactional 标注在类或方法上,声明式事务注解。建议使用@Transactional(rollbackFor = Exception.class)
@Value 使用EL-Spring表达式注入字符、属性、内容等
@JsonSerialize jackson注解,标注在属性或者字段上,指定序列化方式
@JsonProperty(“name”) jackson注解,标注在VO对象的属性上,例如categoryName,返回json中将显示成name
@JsonIgnore jackson注解,标注在POJO对象的属性、方法上,转成json格式时忽略该属性或者方法

4.AOP统一处理请求日志

须要添加 spring-boot-starter-aop 依赖,建立 Aspect 文件便可经过 AOP 统一处理请求日志了:数据库

@Aspect @Component public class HttpAspect { private Logger logger = LoggerFactory.getLogger(getClass()); @Pointcut("execution(public * com.example.server.controller.ContentController.*(..))") public void log() { } //方法执行以前 @Before("log()") public void doBefore(JoinPoint joinPoint) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); //url HttpServletRequest request = attributes.getRequest(); logger.info("url={}", request.getRequestURL()); } //方法执行以后 @After("log()") public void doAfter() { logger.info("doAfter"); } @AfterReturning(returning = "object", pointcut = "log()") public void doAfterReturning(Object object) { logger.info("response={}", object); } }

 

 

5.Spring Boot多线程编程

Spring 经过任务执行器(TaskExecutor)来实现多线程和并发编程。使用 ThreadPoolTaskExecutor 可实现一个基于线程池的 TaskExecutor。而实际开发中任务通常是非阻碍的,即异步的,因此咱们要在配置类中经过 @EnableAsync 开启对异步任务的支持,并经过在实际执行的 Bean 的方法中使用 @ Async 注解来声明是一个异步任务,若是注解在类级别,则表示该类全部的方法都是异步方法。编程

@Configuration @EnableAsync public class TaskExecutorConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(5); taskExecutor.setMaxPoolSize(10); taskExecutor.setQueueCapacity(25); taskExecutor.initialize(); return taskExecutor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return null; } }

 

 

而后声明 @Async 注解,便可并发执行:

@Service public class AsyncTaskService { @Async public void executeAsyncTask(Integer i) { System.out.println("执行异步任务1:" + i); } @Async public void executeAsyncTask2(Integer i) { System.out.println("执行异步任务2:" + i); } }

 

 

6.Spring Boot定时任务

经过在配置类注解 @EnableScheduling 来开启对计划任务的支持,而后在要执行的方法上注解 @Scheduled 声明这是一个计划任务,支持 cron、fixDelay、fixRate 等类型的计划任务。cron 表达式能够去 http://www.pppet.net/ 生成。配置类:

@Configuration @EnableScheduling public class TaskSchedulerConfiguration { }

 

计划任务执行类:

@Service public class ScheduledTaskService { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @Scheduled(fixedRate = 5000) public void reportCurrentTime() { System.out.println("每隔5秒执行1次:" + dateFormat.format(new Date())); } @Scheduled(cron = "0/10 * * * * ? ") public void fixTimeExecution() { System.out.println("在指定时间" + dateFormat.format(new Date()) + "执行"); } }

 

 

运行 Spring Boot 项目,发现计划任务按照计划依次执行成功。

7.Spring Boot配置SSL

使用 jdk 中的 keytool 生成 keystore:

keytool -genkey -alias tomcat

 

这时我就生成了 .keystore 证书文件,将证书文件复制到项目的根目录,而后经过 application.properties 中的 server.ssl.* 前缀配置 SSL 属性便可:

server.ssl.key-store=.keystore server.ssl.key-password=123456 server.ssl.key-store-type=JKS server.ssl.key-alias=tomcat

 

8.Spring Boot加载静态资源

静态资源(css、icon、iconfont、images、img、js)放在 resources/static 下,Freemaker 模版页面放在 resources/templates 下。咱们将Freemaker 模版页面 index.ftl 放入到 resources/templates 下,编写一个 Controller 测试一下:

@Controller public class IndexController { @RequestMapping(value = "index", method = RequestMethod.GET) public String showIndex() { return "index"; } }

 

 

运行访问,发现已经能够访问了。替换 favicon 只须要将本身的 favicon.ico 放置在 resources/static 下便可。除了这些,Spring Boot 还能够加载 WebJars,WebJars 将浏览器资源(css,js等)打成 jar 文件,以对资源进行统一依赖管理,例如添加 bootstrap:

<dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.7-1</version> </dependency>

 

页面引入就能够正常使用了:

<script type="text/javascript" src="/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js"></script>

 

9.Spring Boot单元测试

1.Service单元测试

@RunWith(SpringRunner.class) @SpringBootTest public class ContentServiceTest { @Resource private ContentService contentService; @Test public void whenGetContentListSuccess() throws Exception { Assert.assertNotEquals(0, contentService.getContentList().size()); } }

 

2.Controller单元测试

@RunWith(SpringRunner.class) @SpringBootTest public class ContentControllerTest { @Resource private ContentController contentController; private MockMvc mvc; private Logger logger = LoggerFactory.getLogger(ContentControllerTest.class); @Before public void setup() { mvc = MockMvcBuilders.standaloneSetup(contentController).build(); } @Test public void whenGetContentListSuccess() throws Exception { MvcResult result = mvc.perform(MockMvcRequestBuilders.get("/content/query/list") .contentType(MediaType.APPLICATION_JSON_UTF8)) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn(); logger.info(result.getResponse().getContentAsString()); } }

 

Maven 打包跳过单元测试:

mvn clean package -Dmaven.test.skip=true

 

10.Spring Boot Logback日志配置

Spring Boot 默认使用 SLF4j 和 Logback 输出日志。增长 Logback 配置 resources/logback-spring.xml 便可完成日志文件的生成:

<?xml version="1.0" encoding="UTF-8" ?> <configuration debug="false"> <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern> </layout> </appender> <!-- 天天生成日志文件,并区分info和error日志输出 --> <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern> </encoder> <!--滚动策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--路径--> <fileNamePattern>/var/log/tomcat/PROJECT_NAME/info.%d.log</fileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> </appender> <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern> </encoder> <!--滚动策略--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--路径--> <fileNamePattern>/var/log/tomcat/PROJECT_NAME/error.%d.log</fileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> </appender> <root level="info"> <appender-ref ref="consoleLog" /> <appender-ref ref="fileInfoLog" /> <appender-ref ref="fileErrorLog" /> </root> </configuration>

 

  • spring boot项目发布

Spring Boot 内置了 tomcat-embed,因此能够直接经过 java -jar 的方式运行:

mvn clean package                               //打包
java -jar xx.jar --server.port=9090
java -jar xx.jar --spring.profiles.active=dev   //能够经过java -jar配置参数指定配置文件转载自:https://blog.csdn.net/smartbetter/article/details/53933096#