1。集成Spring & SpringMVC框架
基本的Spring Boot环境已经构建好了,现在需要配置Spring框架及SpringMVC框架的业务环境在AtCrowdfundingApplication类中启用扫描功能,增加@ComponentScan注解
package com.atguigu.crowdfunding; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @ComponentScan(basePackages="com.atguigu") @SpringBootApplication public class AtCrowdfundingApplication { public static void main(String[] args) { SpringApplication.run(AtCrowdfundingApplication.class, args); } }在当前代码中, @ComponentScan注解即使不使用,框架也可以自动进行扫描,但是扫描的包是当前包com.atguigu.crowdfunding和子包com.atguigu.crowdfunding.*
如果还需要扫描其他的包,那么需要增加 @ComponentScan注解
在src/main/java目录中增加类com.atguigu.crowdfunding.controller.MemberController,并增加相应代码。
package com.atguigu.crowdfunding.controller; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/member") public class MemberController { @ResponseBody @RequestMapping("/index") public Object index() { Map map = new HashMap(); map.put("username", "张三"); return map; } }执行AtCrowdfundingApplication类中main方法。然后访问路径http://127.0.0.1:8080/应用路径名称/member/index
页面打印JSON字符串即可
{"username":"张三"}
a.@Controller和@RestController的区别?
官方文档:@RestController is a stereotype annotation that combines @ResponseBody and @Controller.表示@RestController等同于@Controller + @ResponseBody,所以上面的代码可以变为:
package com.atguigu.crowdfunding.controller; import java.util.HashMap; import java.util.Map; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/member") public class MemberController { @RequestMapping("/index") public Object index() { Map map = new HashMap(); map.put("username", "张三"); return map; } }Service接口,ServiceImpl实现类的使用和SSM架构中的使用方式完全相同,详细请 点击链接,这里不做讲解。
2.集成mybatis框架
Spring Boot框架在集成Mybatis框架的时候依然要扫描Dao接口,SQL映射文件以及依赖数据库连接池,但是和传统SSM框架集成时稍微有一些不同。
在项目pom.xml文件中增加Mybaits相关依赖类库(连接池,数据库驱动程序等)
<project> ... <dependencies> ... <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.5</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> ... </dependencies> ... </project>Spring Boot框架中为什么连接池不使用C3P0?
在实际应用中,C3P0偶尔会出现连接超时,或自动断开的情况,虽然会自动重新连接,但是运行稳定性还是存在问题。从性能对比上来说,阿里巴巴开源平台的Druid连接池表现会更好一些。
在src/main/resources/目录下,增加 application.yml配置文件,增加连接池和mybatis相关配置
--- spring: datasource: name: mydb type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://127.0.0.1:3396/atcrowdfunding username: root password: root driver-class-name: com.mysql.jdbc.Driver mybatis: mapperLocations: classpath*:mybatis/mapper-*.xml typeAliasesPackage: com.atguigu.**.bean
a.properties配置文件和.yml配置文件有什么区别?
在 Spring Boot 中,有两种配置文件,一种是application.properties,另一种是application.yml,两种都可以配置Spring Boot 项目中的一些变量的定义,参数的设置等。application.properties 配置文件在写的时候要写完整,yml文件在写的时候层次感强,而且少写了代码。但是从严格意义上来讲,区别不大。扫描Dao接口,需要在AtCrowdfundingApplication类中增加扫描注解 @MapperScan("com.atguigu.**.dao")及事务管理 @EnableTransactionManagement
在src/main/java目录中增加com.atguigu.crowdfunding.dao.MemberDao接口,并增加相应代码
package com.atguigu.crowdfunding.dao; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import com.atguigu.crowdfunding.bean.Member; public interface MemberDao { @Select("select * from t_member where id = #{id}") public Member queryById(Integer id); @Insert("insert into t_member (loginacct) values (#{loginacct})") public int insertMember(Member member); }在src/main/java目录中增加com.atguigu.crowdfunding.bean.Member实体类,并增加相应代码
package com.atguigu.crowdfunding.bean; public class Member { public Integer id; private String loginacct; public String getLoginacct() { return loginacct; } public void setLoginacct(String loginacct) { this.loginacct = loginacct; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } }
传统的SSM架构中采用的是声明式事务,需要在配置文件中增加AOP事务配置,Spring Boot框架中简化了这种配置,可以在Service接口中增加注解@Transactional
package com.atguigu.crowdfunding.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.atguigu.crowdfunding.bean.Member; import com.atguigu.crowdfunding.dao.MemberDao; import com.atguigu.crowdfunding.service.MemberService; @Service @Transactional(readOnly=true) public class MemberServiceImpl implements MemberService { @Autowired private MemberDao memberDao; public Member queryById(Integer id) { return memberDao.queryById(id); } @Transactional public int insertMember(Member member) { return memberDao.insertMember(member); } }
b.@Transactional注解放置在类前和方法前有什么区别?
@Transactional注解放置在类前,表示全局配置,对所有的方法起作用,如果放置在方法前,表示只对这一个方法起作用,且覆盖全局配置。修改MemberController进行测试
package com.atguigu.crowdfunding.controller; import java.util.HashMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.atguigu.crowdfunding.bean.Member; import com.atguigu.crowdfunding.service.MemberService; @RestController @RequestMapping("/member") public class MemberController { @Autowired private MemberService memberService; @RequestMapping("/index") public Object index( Integer id ) { Member member = memberService.queryById(id); return member; } @RequestMapping("/insert") public Object insert( Member member ) { memberService.insertMember(member); return new HashMap(); } }重启服务,访问路径http://127.0.0.1:8080/应用路径名称/member/index观察效果
c.Spring Boot项目在不同的环境下(开发,测试,生产),服务端口不一致怎么办?
Spring Boot针对于不同的环境提供了Profile支持。通过profile的设定来查找不同的配置文件,如在application.properties配置文件中增加配置参数spring.profiles.active=test,那么框架会自动读取application-test.properties文件,在不同的配置文件中设定不同的端口号(81,82。。。)即可。也可以将项目打包成jar,输入命令行参数:java -jar xxx.jar --spring.profiles.active=test3.模板视图 - freemarker
项目中采用freemarker作为展示视图,需要在项目pom.xml配置文件中增加依赖关系。
<project> ... <dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> ... </dependencies> ... </project>在application.properties配置文件中增加freemarker相关配置。
... spring.freemarker.allow-request-override=false spring.freemarker.allow-session-override=false spring.freemarker.cache=true spring.freemarker.charset=UTF-8 spring.freemarker.check-template-location=true spring.freemarker.content-type=text/html spring.freemarker.enabled=true spring.freemarker.expose-request-attributes=false spring.freemarker.expose-session-attributes=false spring.freemarker.expose-spring-macro-helpers=true spring.freemarker.prefer-file-system-access=false spring.freemarker.suffix=.ftl spring.freemarker.template-loader-path=classpath:/templates/ spring.freemarker.settings.template_update_delay=0 spring.freemarker.settings.default_encoding=UTF-8 spring.freemarker.settings.classic_compatible=true spring.freemarker.order=1 ...在src/main/resources/目录中增加templates文件夹,并增加memberIndex.ftl文件
FREEMARKER INDEX PAGE!!!修改MemberController进行测试
package com.atguigu.crowdfunding.controller; import java.util.HashMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.transaction.annotation.EnableTransactionManagement; import com.atguigu.crowdfunding.bean.Member; import com.atguigu.crowdfunding.service.MemberService; @Controller @RequestMapping("/member") public class MemberController { @Autowired private MemberService memberService; @RequestMapping("/index") public String index() { return "memberIndex"; } @RequestMapping("/insert") public Object insert( Member member ) { memberService.insertMember(member); return new HashMap(); } }
a.Spring Boot中为什么不采用JSP作为视图模板?
Spring Boot框架一般是打包为JAR执行,而JSP在web工程(war包)中可以被java程序读取和识别,但是在JAR包中是比较困难的。所以需要采用其他的模板视图技术。4.热部署
项目开发过程中,常常会改动页面数据或者修改数据结构,为了显示改动效果,往往需要重启应用查看改变效果,其实就是重新编译生成了新的 Class 文件,这个文件里记录着和代码等对应的各种信息,然后 Class 文件将被虚拟机的 ClassLoader 加载。而热部署正是利用了这个特点,它监听到如果有 Class 文件改动了,就会创建一个新的 ClaassLoader 进行加载该文件,经过一系列的过程,最终将结果呈现在我们眼前。Spring Boot 实现热部署很简单,在pom.xml中增加相关依赖即可
<dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional><!-- 这个需要为 true 热部署才有效--> </dependency> ... </dependencies>
5.分布式集群 - 集成Nginx
因为Spring Boot框架内嵌Tomcat服务器,所以本章的分布式集群依然是基于Tomcat + NginxNginx作为反向代理服务器,收到请求后将通过http协议转发给Tomcat,所以Tomcat需要从从HTTP头信息中去获取协议信息。在application.properties中增加配置信息。
... server.address=127.0.0.1 server.tomcat.remote-ip-header=x-forwarded-for server.tomcat.protocol-header=x-forwarded-proto server.tomcat.port-header=X-Forwarded-Port server.use-forward-headers=true ...Spring Boot框架在集群时需要设置Session共享,框架当前只支持Redis缓存作为Session共享组件。
a.在项目pom.xml配置文件中增加Redis依赖关系。
<project> ... <dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> ... </dependencies> ... </project>
b.在application.properties配置文件中增加Redis相关配置。
... spring.session.store-type=redis spring.redis.database=1 spring.redis.host=127.0.0.1 spring.redis.password=123123 spring.redis.port=6379 spring.redis.pool.max-idle=8 spring.redis.pool.min-idle=0 spring.redis.pool.max-active=8 spring.redis.pool.max-wait=-1 spring.redis.timeout=60000 ...
c.增加集成配置类RedisSessionConfig
@Configuration @EnableRedisHttpSession public class RedisSessionConfig { }设置Redis Session共享后,如果向Session中保存数据,需要让数据对象实现可序列化接口java.io.Serializable!!!
分别启动Nginx, 2个Web应用,观察是否集成成功
d.如何将Spring Boot项目发布为war包独立部署?
1)将当前的项目打包方式设置为war。2)将项目中tomcat模块的依赖类库设置为provided。
... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> ...3)将当前Application启动类继承SpringBootServletInitializer, 并重写方法configure。
@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { builder.sources(Application.class);// Application为启动类 return super.configure(builder); }
6.健康监控
在生产环境中,需要实时或定期监控服务的可用性。Spring Boot 的actuator(监控)功能提供了很多监控所需的接口。在pom.xml文件中增加依赖关系
... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ...
在application.yml配置文件中指明监控端口,如果未指明,那么监控端口和当前应用端口一致。
... management: port: 8400 ...输入网址http://localhost:8400/health查看健康指标
{"description":"Spring Cloud Eureka Discovery Client","status":"UP","discoveryComposite":{"description":"Spring Cloud Eureka Discovery Client","status":"UP","discoveryClient":{"description":"Spring Cloud Eureka Discovery Client","status":"UP","services":["eureka-service-member","unknown"]},"eureka":{"description":"Remote status from Eureka server","status":"UP","applications":{"EUREKA-SERVICE-MEMBER":1,"UNKNOWN":1}}},"diskSpace":{"status":"UP","total":290389487616,"free":98902450176,"threshold":10485760},"redis":{"status":"UP","version":"3.0.500"},"db":{"status":"UP","database":"MySQL","hello":1},"refreshScope":{"status":"UP"},"configServer":{"status":"UNKNOWN","error":"no property sources located"},"hystrix":{"status":"UP"}}在 application.yml配置文件中增加环境信息,数据可从pom.xml文件中获取
... info: app: name: "@project.name@" #从pom.xml中获取 description: "@project.description@" version: "@project.version@" spring-boot-version: "@project.parent.version@" ...
输入网址http://localhost:8400/info查看配置
{"app":{"name":"springboot-member","description":"Parent pom providing dependency and plugin management for applications built with Maven","version":"1.0","spring-boot-version":"1.5.7.RELEASE"}}
具体监控指标如下: