Spring Boot 快速构建应用程序

Spring Boot 简化了 Spring 应用开发,不需要配置就能运行 Spring 应用,Spring Boot 的自动配置是通过 Spring 4.x 的条件注解 @Conditional 来实现的,@Conditional 根据特定条件来控制 bean 的创建行为。Spring Boot 默认会使用内置的 Tomcat,并支持 Spring MVC、RESTful 服务。

1.Spring Boot的使用

新建 Spring Boot 项目很简单,IntelliJ IDEA 在 New Project 中选择 Spring Initializr,然后组件选择 Web (集成 Spring MVC 框架) 即可创建成功。Spring Boot 通过 Starter 来提供系统级服务,Spring Boot 已经提供了一系列的 Starter:

说明
spring-boot-starter-webWeb开发支持,默认使用Tomcat8
spring-boot-starter-aopAOP开发支持,使用AspectJ
spring-boot-starter-test包含JUnit、Spring Test、Hamcrest、Mockito等测试工具
spring-boot-starter-jdbcSpring JDBC
spring-boot-starter-cache缓存,支持多种缓存方式,如本地的、Redis、Ehcache等
spring-boot-starter-activemq消息集成ActiveMQ支持
spring-boot-starter-amqp消息集成AMQP协议支持,如支持RabbitMQ
spring-boot-starter-web-serviceswebservice支持
spring-boot-starter-websocketwebsocket支持
spring-boot-starter-jerseyREST应用和Jersey支持
spring-boot-starter-freemarkerFreemarker模板引擎支持
spring-boot-starter-thymeleafThymeleaf模板引擎支持
spring-boot-starter-jta-atomikos分布式事务支持,使用atomikos
spring-boot-starter-jta-bitronix一个开源的分布式事务支持
spring-boot-starter-data-jpaJPA方式访问数据库,使用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.多环境配置

Spring Boot 允许你通过 application-{profile}.properties 格式来定义多个配置文件,然后在 application.properyies 通过 spring.profiles.active 来具体激活一个或者多个配置文件,例如新建 resources/application-test.properties,然后在 application.properyies 中激活这个配置:

spring.profiles.active=test
# 自定义
example.str=hello

Spring 通过注解获取 *.porperties 文件的内容,除了 xml 配置外,还可以通过 @Value 方式来获取:

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

2.JavaConfig

Spring Boot 推荐使用 Java 代码的形式声明注册 bean,@Configuration 注解可以用 Java 代码的形式实现 Spring 中 xml 配置文件配置的效果:

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

3.构建Spring MVC应用

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

常用注解释义
@RestControllerSpring4之后新加的注解,等同于@ResponseBody+@Controller
@RequestMappingurl映射,value可以为数组,例如{"/hello", “/hi”}
@GetMappingGET类型的url映射,还有@PostMapping、@PutMapping、@DeleteMapping
@PathVariable获取url中的数据
@RequestParam获取请求参数的值,required属性表示是否必传,defaultValue属性表示默认值
@RequestBody用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如application/json或application/xml等。
@Component通用注解,会被注册为bean组件、基于它的还有@Repository、@Service、@Controller
@Autowired标注在构造方法、类的任何方法上,实现自动装配
@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配
@Lazy(true)表示延迟初始化
@Import导入配置类,并支持导入普通的java类,并将其声明成一个bean
@Transactional标注在类或方法上,声明式事务注解。建议使用@Transactional(rollbackFor = Exception.class),另外 RuntimeException 及其子类 或 Error 及其子类 会默认回滚,这部分源码在 RuleBasedTransactionAttribute#rollbackOn
@Value使用EL-Spring表达式注入字符、属性、内容等
@JsonSerializejackson注解,标注在属性或者字段上,指定序列化方式
@JsonProperty(“name”)jackson注解,标注在VO对象的属性上,例如categoryName,返回json中将显示成name
@JsonIgnorejackson注解,标注在POJO对象的属性、方法上,转成json格式时忽略该属性或者方法

新建 HelloController:

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

mvn spring-boot:run 命令运行项目,浏览器访问 http://localhost:8081/hello,即可看到输出结果 “Hello, Spring Boot!”。

4.AOP支持

Spring Boot 使用 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 通过任务执行器(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.定时任务支持

通过在配置类注解 @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()) + "执行");
    }
}

7.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.加载静态资源

静态资源(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.单元测试

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.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>

11.项目发布

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配置参数指定配置文件
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值