- SpringBoot简介
- 使用JdbcTemplate">springboot整合使用JdbcTemplate
- 使用mybatis">springboot整合使用mybatis
- 使用springjpa">springboot整合使用springjpa
- springboot整合多数据源
- Springboot整合事物管理
- SpringBoot分布式事物管理
- 日志管理
- 使用AOP统一处理Web请求日志
">使用AOP统一处理Web请求日志 - Spring Boot集成lombok让代码更简洁
- 缓存支持
- 使用@Scheduled创建定时任务">使用@Scheduled创建定时任务
- 使用@Async实现异步调用">使用@Async实现异步调用
- 自定义参数
- 多环境配置
- 热部署
- 监控管理
- Admin-UI分布式微服务监控中心
- 组件自动扫描带来的问题
- SpringBoot JVM参数调优
- 2.0版本新特性
- 支持Quartz Scheduler
- OAuth 2.0 支持
- 支持Spring WebFlux
- SpringBoot整合拦截器
- 发布打包
- SpringBoot框架原理
SpringBoot简介
在您第1次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复黏贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot来让你更易上手,更简单快捷地构建Spring应用!
Spring
Boot让我们的Spring应用变的更轻量化。比如:你可以仅仅依靠一个Java类来运行一个Spring引用。你也可以打包你的应用为jar并通过使用java -jar来运行你的Spring Web应用。
Spring
Boot的主要优点:
为所有Spring开发者更快的入门
开箱即用,提供各种默认配置来简化项目配置
内嵌式容器简化Web项目
没有冗余代码生成和XML配置的要求
本章主要目标完成Spring Boot基础项目的构建,并且实现一个简单的Http请求处理,通过这个例子对Spring Boot有一个初步的了解,并体验其结构简单、开发快速的特性。
SpringBoot
是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。
SpringMVC是控制层。
SpringBoot和SpringMVC区别:
SpringBoot
是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。
SpringMVC是控制层。
SpringBoot和SpringCloud区别:
SpringBoot
是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件 默认集成的是SpringMVC框架。
SpringMVC是控制层。
SpringCloud依赖与SpringBoot组件,使用SpringMVC编写Http协议接口,同时SpringCloud是一套完整的微服务解决框架。
spring-boot-starter-parent作用
在pom.xml中引入spring-boot-start-parent,spring官方的解释叫什么stater poms,它可以提供dependency management,也就是说依赖管理,引入以后在申明其它dependency的时候就不需要version了,后面可以看到。
_spring-boot-starter-web**作用
springweb
核心组件
**
spring-boot-maven-plugin**作用**_
如果我们要直接Main启动spring,那么以下plugin必须要添加,否则是无法启动的。如果使用maven 的spring-boot:run的话是不需要此配置的。(我在测试的时候,如果不配置下面的plugin也是直接在Main中运行的。)
相关注解:
@RestController
在上加上RestController 表示修饰该Controller所有的方法返回JSON格式,直接可以编写
Restful接口
@EnableAutoConfiguration
注解:作用在于让 Spring Boot 根据应用所声明的依赖来对 Spring 框架进行自动配置
这个注解告诉Spring Boot根据添加的jar依赖猜测你想如何配置Spring。由于spring-boot-starter-web添加了Tomcat和Spring MVC,所以auto-configuration将假定你正在开发一个web应用并相应地对Spring进行设置。
SpringApplication.run(HelloController.class, args);
标识为启动类
springboot整合使用JdbcTemplate
1.引入pom文件
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.2.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.21</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
2.application.properties新增配置
spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.jdbc.Driver
UserService类
@Servicepublic class UserServiceImpl implements UserService {@Autowiredprivate JdbcTemplate jdbcTemplate;public void createUser(String name, Integer age) {System.out.println("ssss");jdbcTemplate.update("insert into users values(null,?,?);", name, age);}}
App类
@ComponentScan(basePackages = "com.itmayiedu")@EnableAutoConfigurationpublic class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}
springboot整合使用mybatis
1.pom文件引入
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.3.2.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.1.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.21</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
2.配置文件引入
spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.jdbc.Driver
3.Mapper代码
public interface UserMapper {@Select("SELECT * FROM USERS WHERE NAME = #{name}")User findByName(@Param("name") String name);@Insert("INSERT INTO USERS(NAME, AGE) VALUES(#{name}, #{age})")int insert(@Param("name") String name, @Param("age") Integer age);}
启动方式:
@ComponentScan(basePackages = "com.itmayiedu")@MapperScan(basePackages = "com.itmayiedu.mapper")@SpringBootApplicationpublic class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}
springboot整合使用springjpa
1.pom文件引入依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.4.2.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.21</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
2.创建User实体类
@Entity(name = "users")public class User {@Id@GeneratedValueprivate Integer id;@Columnprivate String name;@Columnprivate Integer age;// ..get/set方法}
3.创建UserDao
public interface UserDao extends JpaRepository<User, Integer> {}
4.创建IndexController
@RestControllerpublic class IndexController {@Autowiredprivate UserDao userDao;@RequestMapping("/index")public String index(Integer id) {User findUser = userDao.findOne(id);System.out.println(findUser.getName());return "success";}}
5.启动项目
@ComponentScan(basePackages = { "com.itmayiedu" })@EnableJpaRepositories(basePackages = "com.itmayiedu.dao")@EnableAutoConfiguration@EntityScan(basePackages = "com.itmayiedu.entity")public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}
springboot整合多数据源
。。。
Springboot整合事物管理
springboot默认集成事物,只主要在方法上加上@Transactional即可
SpringBoot分布式事物管理
使用springboot+jta+atomikos 分布式事物管理
1新增pom包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jta-atomikos</artifactId></dependency>
2.新增配置文件信息
# Mysql 1mysql.datasource.test.url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8mysql.datasource.test.username = rootmysql.datasource.test.password = rootmysql.datasource.test.minPoolSize = 3mysql.datasource.test.maxPoolSize = 25mysql.datasource.test.maxLifetime = 20000mysql.datasource.test.borrowConnectionTimeout = 30mysql.datasource.test.loginTimeout = 30mysql.datasource.test.maintenanceInterval = 60mysql.datasource.test.maxIdleTime = 60mysql.datasource.test.testQuery = select 1# Mysql 2mysql.datasource.test2.url =jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8mysql.datasource.test2.username =rootmysql.datasource.test2.password =rootmysql.datasource.test2.minPoolSize = 3mysql.datasource.test2.maxPoolSize = 25mysql.datasource.test2.maxLifetime = 20000mysql.datasource.test2.borrowConnectionTimeout = 30mysql.datasource.test2.loginTimeout = 30mysql.datasource.test2.maintenanceInterval = 60mysql.datasource.test2.maxIdleTime = 60mysql.datasource.test2.testQuery = select 1
3.读取配置文件信息
package com.itmayiedu.config;import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix = "mysql.datasource.test")public class DBConfig1 {private String url;private String username;private String password;private int minPoolSize;private int maxPoolSize;private int maxLifetime;private int borrowConnectionTimeout;private int loginTimeout;private int maintenanceInterval;private int maxIdleTime;private String testQuery;}package com.itmayiedu.config;import org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix = "mysql.datasource.test1")public class DBConfig2 {private String url;private String username;private String password;private int minPoolSize;private int maxPoolSize;private int maxLifetime;private int borrowConnectionTimeout;private int loginTimeout;private int maintenanceInterval;private int maxIdleTime;private String testQuery;}
4.创建多数据源
@Configuration// basePackages 最好分开配置 如果放在同一个文件夹可能会报错@MapperScan(basePackages = "com.itmayiedu.test1", sqlSessionTemplateRef = "testSqlSessionTemplate")public class TestMyBatisConfig1 {// 配置数据源@Primary@Bean(name = "testDataSource")public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();mysqlXaDataSource.setUrl(testConfig.getUrl());mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);mysqlXaDataSource.setPassword(testConfig.getPassword());mysqlXaDataSource.setUser(testConfig.getUsername());mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();xaDataSource.setXaDataSource(mysqlXaDataSource);xaDataSource.setUniqueResourceName("testDataSource");xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());xaDataSource.setTestQuery(testConfig.getTestQuery());return xaDataSource;}@Primary@Bean(name = "testSqlSessionFactory")public SqlSessionFactory testSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource)throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);return bean.getObject();}@Primary@Bean(name = "testSqlSessionTemplate")public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {return new SqlSessionTemplate(sqlSessionFactory);}}// basePackages 最好分开配置 如果放在同一个文件夹可能会报错@Configuration@MapperScan(basePackages = "com.itmayiedu.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")public class TestMyBatisConfig2 {// 配置数据源@Bean(name = "test2DataSource")public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();mysqlXaDataSource.setUrl(testConfig.getUrl());mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);mysqlXaDataSource.setPassword(testConfig.getPassword());mysqlXaDataSource.setUser(testConfig.getUsername());mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();xaDataSource.setXaDataSource(mysqlXaDataSource);xaDataSource.setUniqueResourceName("test2DataSource");xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());xaDataSource.setTestQuery(testConfig.getTestQuery());return xaDataSource;}@Bean(name = "test2SqlSessionFactory")public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);return bean.getObject();}@Bean(name = "test2SqlSessionTemplate")public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {return new SqlSessionTemplate(sqlSessionFactory);}}
5.启动加载配置
@EnableConfigurationProperties(value = { DBConfig1.class, DBConfig2.class })
日志管理
新建log4j配置文件
文件名称log4j.properties
#log4j.rootLogger=CONSOLE,info,error,DEBUGlog4j.rootLogger=info,error,CONSOLE,DEBUGlog4j.appender.CONSOLE=org.apache.log4j.ConsoleAppenderlog4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayoutlog4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%nlog4j.logger.info=infolog4j.appender.info=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.info.layout=org.apache.log4j.PatternLayoutlog4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%nlog4j.appender.info.datePattern='.'yyyy-MM-ddlog4j.appender.info.Threshold = infolog4j.appender.info.append=true#log4j.appender.info.File=/home/admin/pms-api-services/logs/info/api_services_infolog4j.appender.info.File=/Users/dddd/Documents/testspace/pms-api-services/logs/info/api_services_infolog4j.logger.error=errorlog4j.appender.error=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.error.layout=org.apache.log4j.PatternLayoutlog4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%nlog4j.appender.error.datePattern='.'yyyy-MM-ddlog4j.appender.error.Threshold = errorlog4j.appender.error.append=true#log4j.appender.error.File=/home/admin/pms-api-services/logs/error/api_services_errorlog4j.appender.error.File=/Users/dddd/Documents/testspace/pms-api-services/logs/error/api_services_errorlog4j.logger.DEBUG=DEBUGlog4j.appender.DEBUG=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.DEBUG.layout=org.apache.log4j.PatternLayoutlog4j.appender.DEBUG.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%nlog4j.appender.DEBUG.datePattern='.'yyyy-MM-ddlog4j.appender.DEBUG.Threshold = DEBUGlog4j.appender.DEBUG.append=true#log4j.appender.DEBUG.File=/home/admin/pms-api-services/logs/debug/api_services_debuglog4j.appender.DEBUG.File=/Users/dddd/Documents/testspace/pms-api-services/logs/debug/api_services_debug
log4j代码private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
Maven依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent><dependencies><!-- SpringBoot 核心组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></dependency><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId></dependency><!-- spring boot start --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><!-- 排除自带的logback依赖 --><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!-- springboot-log4j --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j</artifactId><version>1.3.8.RELEASE</version></dependency></dependencies>
使用AOP统一处理Web请求日志
1.POM文件新增依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
相关代码
@Aspect@Componentpublic class WebLogAspect {private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);@Pointcut("execution(public * com.itmayiedu.controller.*.*(..))")public void webLog() {}@Before("webLog()")public void doBefore(JoinPoint joinPoint) throws Throwable {// 接收到请求,记录请求内容ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();// 记录下请求内容logger.info("URL : " + request.getRequestURL().toString());logger.info("HTTP_METHOD : " + request.getMethod());logger.info("IP : " + request.getRemoteAddr());Enumeration<String> enu = request.getParameterNames();while (enu.hasMoreElements()) {String name = (String) enu.nextElement();logger.info("name:{},value:{}", name, request.getParameter(name));}}@AfterReturning(returning = "ret", pointcut = "webLog()")public void doAfterReturning(Object ret) throws Throwable {// 处理完请求,返回内容logger.info("RESPONSE : " + ret);}}
Spring Boot集成lombok让代码更简洁
添加lombok依赖
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
实体类演示
@Slf4j@Datapublic class UserEntity {// @Getter// @Setterprivate String userName;// @Getter// @Setterprivate Integer age;@Overridepublic String toString() {return "UserEntity [userName=" + userName + ", age=" + age + "]";}public static void main(String[] args) {UserEntity userEntity = new UserEntity();userEntity.setUserName("zhangsan");userEntity.setAge(20);System.out.println(userEntity.toString());log.info("####我是日志##########");}}
其他特性
@Data 标签,生成getter/setter toString()等方法@NonNull : 让你不在担忧并且爱上NullPointerException@CleanUp : 自动资源管理:不用再在finally中添加资源的close方法@Setter/@Getter : 自动生成set和get方法@ToString : 自动生成toString方法@EqualsAndHashcode : 从对象的字段中生成hashCode和equals的实现@NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor自动生成构造方法@Data : 自动生成set/get方法,toString方法,equals方法,hashCode方法,不带参数的构造方法@Value : 用于注解final类@Builder : 产生复杂的构建器api类@SneakyThrows : 异常处理(谨慎使用)@Synchronized : 同步方法安全的转化@Getter(lazy=true) :@Log : 支持各种logger对象,使用时用对应的注解,如:@Log4
缓存支持
注解配置与EhCache使用
pom文件引入
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>
新建ehcache.xml 文件
<?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"updateCheck="false"><diskStore path="java.io.tmpdir/Tmp_EhCache" /><!-- 默认配置 --><defaultCache maxElementsInMemory="5000" eternal="false"timeToIdleSeconds="120" timeToLiveSeconds="120"memoryStoreEvictionPolicy="LRU" overflowToDisk="false" /><cache name="baseCache" maxElementsInMemory="10000"maxElementsOnDisk="100000" /></ehcache>配置信息介绍1. <!--2. name:缓存名称。3. maxElementsInMemory:缓存最大个数。4. eternal:对象是否永久有效,一但设置了,timeout将不起作用。5. timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。6. timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。7. overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。8. diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。9. maxElementsOnDisk:硬盘最大缓存个数。10. diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.11. diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。12. memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。13. clearOnFlush:内存数量最大时是否清除。14. -->
代码使用Cacheable
@CacheConfig(cacheNames = "baseCache")public interface UserMapper {@Select("select * from users where name=#{name}")@CacheableUserEntity findName(@Param("name") String name);}
清除缓存
@Autowiredprivate CacheManager cacheManager;@RequestMapping("/remoKey")public void remoKey() {cacheManager.getCache("baseCache").clear();}
启动加入缓存
@EnableCaching
// 开启缓存注解
使用@Scheduled创建定时任务
在Spring Boot的主类中加入@EnableScheduling注解,启用定时任务的配置
@Componentpublic class ScheduledTasks {private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");@Scheduled(fixedRate = 5000)public void reportCurrentTime() {System.out.println("现在时间:" + dateFormat.format(new Date()));}}
使用@Async实现异步调用
启动加上@EnableAsync ,需要执行异步方法上加入 @Async
在方法上加上@Async之后 底层使用多线程技术
_
_
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
演示代码:
@RestController@Slf4jpublic class IndexController {@Autowiredprivate UserService userService;@RequestMapping("/index")public String index() {log.info("##01##");userService.userThread();log.info("##04##");return "success";}}@Service@Slf4jpublic class UserService {@Async // 类似与开启线程执行..public void userThread() {log.info("##02##");try {Thread.sleep(5 * 1000);} catch (Exception e) {// TODO: handle exception}log.info("##03##");// new Thread(new Runnable() {// public void run() {// log.info("##02##");// try {// Thread.sleep(5 * 1000);// } catch (Exception e) {// // TODO: handle exception// }// log.info("##03##");// }// }).start();}}@EnableAsync // 开启异步注解@SpringBootApplicationpublic class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}
自定义参数
配置文件值
name=itmayiedu.com
配置文件值
@Value("${name}")private String name;@ResponseBody@RequestMapping("/getValue")public String getValue() {return name;}
多环境配置
spring.profiles.active=pre
application-dev.properties:开发环境application-test.properties:测试环境application-prod.properties:生产环境
热部署
所谓的热部署:比如项目的热部署,就是在应用程序在不停止的情况下,实现新的部署
项目演示案例:
@RestController@Slf4jpublic class IndexController {@Value("${itmayiedu}")private String itmayieduName;@RequestMapping("/index")public String index() {String result = "springboot2.0 V1.0";log.info("result:{}", result);return result + itmayieduName;}}
热部署原理:
spring-boot-devtools
是一个为开发者服务的一个模块,其中最重要的功能就是自动应用代码更改到最新的App上面去。原理是在发现代码有更改之后,重新启动应用,但是速度比手动停止后再启动还要更快,更快指的不是节省出来的手工操作的时间。
其深层原理是使用了两个ClassLoader,一个Classloader加载那些不会改变的类(第三方Jar包),另一个ClassLoader加载会更改的类,称为 restart ClassLoader
_
,这样在有代码更改的时候,原来的restart ClassLoader 被丢弃,重新创建一个restart
ClassLoader,由于需要加载的类相比较少,所以实现了较快的重启时间(5秒以内)
Devtools依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional><scope>true</scope></dependency>
Devtools原理:
- devtools会监听classpath下的文件变动,并且会立即重启应用(发生在保存时机),注意:因为其采用的虚拟机机制,该项重启是很快的。
- devtools可以实现页面热部署(即页面修改后会立即生效,这个可以直接在application.properties文件中配置spring.thymeleaf.cache=false来实现(这里注意不同的模板配置不一样)
监控管理
Actuator监控应用
Actuator是spring boot的一个附加功能,可帮助你在应用程序生产环境时监视和管理应用程序。可以使用HTTP的各种请求来监管,审计,收集应用的运行情况.特别对于微服务管理十分有意义.缺点:没有可视化界面。
Maven依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies>
YML配置
###通过下面的配置启用所有的监控端点,默认情况下,这些端点是禁用的;management:endpoints:web:exposure:include: "*"spring:profiles:active: proddatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/testusername: rootpassword: rootitmayiedu:name: yushengjun
Actuator访问路径
通过actuator/+端点名就可以获取相应的信息。
| 路径 | 作用 |
|---|---|
| /actuator/beans | 显示应用程序中所有Spring bean的完整列表。 |
| /actuator/configprops | 显示所有配置信息。 |
| /actuator/env | 陈列所有的环境变量。 |
| /actuator/mappings | 显示所有@RequestMapping的url整理列表。 |
| /actuator/health | 显示应用程序运行状况信息 up表示成功 down失败 |
| /actuator/info | 查看应用信息 |
演示案例:
/actuator/info 配置文件新增
info:itmayiedu: yushengjunaddres: www.itmayiedu.com
Admin-UI分布式微服务监控中心
Admin-UI基于actuator实现能够返回界面展示监控信息
Admin-UI-Server
Maven依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent><dependencies><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.0.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><!-- Spring Boot Actuator对外暴露应用的监控信息,Jolokia提供使用HTTP接口获取JSON格式 的数据 --><dependency><groupId>org.jolokia</groupId><artifactId>jolokia-core</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>com.googlecode.json-simple</groupId><artifactId>json-simple</artifactId><version>1.1</version></dependency></dependencies>
application.yml配置文件
spring:application:name: spring-boot-admin-server
启动方式
@Configuration@EnableAutoConfiguration@EnableAdminServerpublic class AdminServerApplication {public static void main(String[] args) {SpringApplication.run(AdminServerApplication.class, args);}}
Admin-UI-Client
Maven依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent><dependencies><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>2.0.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.jolokia</groupId><artifactId>jolokia-core</artifactId></dependency><dependency><groupId>com.googlecode.json-simple</groupId><artifactId>json-simple</artifactId><version>1.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
YML配置
spring:boot:admin:client:url: http://localhost:8080server:port: 8081management:endpoints:web:exposure:include: "*"endpoint:health:show-details: ALWAYS
启动类
@SpringBootApplicationpublic class AppClinet {public static void main(String[] args) {SpringApplication.run(AppClinet.class, args);}}

组件自动扫描带来的问题
默认情况下,我们会使用 @SpringBootApplication 注解来自动获取应用的配置信息,但这样也会给应用带来一些副作用。使用这个注解后,会触发自动配置( auto-configuration )和 组件扫描 ( component scanning ),这跟使用 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 三个注解的作用是一样的。这样做给开发带来方便的同时,也会有三方面的影响:
1、会导致项目启动时间变长。当启动一个大的应用程序,或将做大量的集成测试启动应用程序时,影响会特别明显。
2、会加载一些不需要的多余的实例(beans)。
3、会增加 CPU 消耗。
针对以上三个情况,我们可以移除 @SpringBootApplication 和 @ComponentScan 两个注解来禁用组件自动扫描,然后在我们需要的 bean 上进行显式配置:
//// 移除 @SpringBootApplication and @ComponentScan, 用 @EnableAutoConfiguration 来替代//@SpringBootApplication@Configuration@EnableAutoConfigurationpublic class App01 {public static void main(String[] args) {SpringApplication.run(App01.class, args);}}
以@SpringBootApplication 启动时间8.56秒
将Servlet容器变成Undertow
默认情况下,Spring Boot 使用 Tomcat 来作为内嵌的 Servlet 容器
可以将 Web 服务器切换到 Undertow 来提高应用性能。Undertow 是一个采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。Undertow 是红帽公司的开源产品,是 Wildfly 默认的 Web 服务器。首先,从依赖信息里移除 Tomcat 配置:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency>然后添加 Undertow:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency>
SpringBoot JVM参数调优
这个根据服务器的内存大小,来设置堆参数。
-Xms :设置Java堆栈的初始化大小
-Xmx :设置最大的java堆大小
实例参数-XX:+PrintGCDetails -Xmx32M -Xms1M
本地项目调优
外部运行调优java -server
-Xms32m -Xmx32m -jar springboot_v2.jar
| 服务器名称 | 第一次运行 | 第二次运行 | 第三次运行 | 平均值 |
|---|---|---|---|---|
| Tomcat | 4773 | 5194 | 5334.7 | 5100 |
| Undertow | 6666 | 6373 | 6451 | 6496 |
2.0版本新特性
以Java 8 为基准
Spring
Boot 2.0 要求Java 版本必须8以上, Java 6
和 7 不再支持。
内嵌容器包结构调整:
为了支持reactive使用场景,内嵌的容器包结构被重构了的幅度有点大。EmbeddedServletContainer被重命名为WebServer,并且org.springframework.boot.context.embedded
包被重定向到了org.springframework.boot.web.embedded包下。举个例子,如果你要使用TomcatEmbeddedServletContainerFactory回调接口来自定义内嵌Tomcat容器,你现在应该使用TomcatServletWebServerFactory。
Servlet-specific 的server properties调整
大量的Servlet专属的server.* properties被移到了server.servlet下:
| Old property | New property |
|---|---|
| server.context-parameters.* | server.servlet.context-parameters.* |
| server.context-path | server.servlet.context-path |
| server.jsp.class-name | server.servlet.jsp.class-name |
| server.jsp.init-parameters.* | server.servlet.jsp.init-parameters.* |
| server.jsp.registered | server.servlet.jsp.registered |
| server.servlet-path | server.servlet.path |
由此可以看出一些端倪,那就是server不再是只有servlet了,还有其他的要加入。
Actuator 默认映射
ctuator的端点(endpoint)现在默认映射到/application,比如,/info 端点现在就是在/application/info。但你可以使用management.context-path来覆盖此默认值。
Spring Loaded不再支持
由于Spring Loaded项目已被移到了attic了,所以不再支持Spring Loaded了。现在建议你去使用Devtools。Spring Loaded不再支持了。
支持Quartz Scheduler
Spring Boot 2 针对Quartz调度器提供了支持。你可以加入spring-boot-starter-quartz starter来启用。而且支持基于内存和基于jdbc两种存储。
OAuth 2.0 支持
Spring Security OAuth 项目中的功能将会迁移到Spring Security中。将会OAuth 2.0。
支持Spring WebFlux
WebFlux
模块的名称是
spring-webflux,名称中的 Flux 来源于
Reactor 中的类 Flux。该模块中包含了对反应式
HTTP、服务器推送事件和 WebSocket 的客户端和服务器端的支持。对于开发人员来说,比较重要的是服务器端的开发,这也是本文的重点。在服务器端,WebFlux 支持两种不同的编程模型:第一种是 Spring MVC 中使用的基于 Java 注解的方式;第二种是基于 Java 8 的 lambda 表达式的函数式编程模型。这两种编程模型只是在代码编写方式上存在不同。它们运行在同样的反应式底层架构之上,因此在运行时是相同的。WebFlux 需要底层提供运行时的支持,WebFlux 可以运行在支持 Servlet 3.1 非阻塞 IO API 的 Servlet 容器上,或是其他异步运行时环境,如 Netty 和 Undertow。
_
版本要求:
Jetty
要求Jetty最低版本为9.4。
Tomcat
要求Tomcat最低版本为8.5。
Hibernate
要求Hibernate最低版本为5.2。
Gradle
要求Gradle最低版本为3.4。
SendGrid
SendGrid最低支持版本是3.2。为了支持这次升级,username和password已经被干掉了。因为API key现在是唯一支持的认证方式。
SpringBoot整合拦截器
创建拦截器
创建模拟登录拦截器,验证请求是否有token参数
@Slf4j@Componentpublic class LoginIntercept implements HandlerInterceptor {public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {log.info("开始拦截登录请求....");String token = request.getParameter("token");if (StringUtils.isEmpty(token)) {response.getWriter().println("not found token");return false;}return true;}}
注册拦截器
@Configurationpublic class WebAppConfig {@Autowiredprivate LoginIntercept loginIntercept;@Beanpublic WebMvcConfigurer WebMvcConfigurer() {return new WebMvcConfigurer() {public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginIntercept).addPathPatterns("/*");};};}}
拦截器与过滤器区别
拦截器是AOP( Aspect-Oriented Programming)的一种实现,底层通过动态代理模式完成。
(1)拦截器是基于java的反射机制的,而过滤器是基于函数回调。
(2)拦截器不依赖于servlet容器,而过滤器依赖于servlet容器。
(3)拦截器只能对Controller请求起作用,而过滤器则可以对几乎所有的请求起作用。
(4)在Controller的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
过滤器应用场景:设置编码字符、过滤铭感字符
拦截器应用场景:拦截未登陆用户、审计日志()
发布打包
一.Jar类型打包方式
1.使用mvn celan package 打包
2.使用java –jar 包名
二.war类型打包方式
1.使用mvn celan package 打包
2.使用java –jar 包名
外部Tomcat运行
1.使用mvn celan package 打包
2.2.0将war包 放入到tomcat webapps下运行即可。
注意:springboot2.0内置tomcat8.5.25,建议使用外部Tomcat9.0版本运行即可,否则报错版本不兼容。
SpringBoot框架原理
SpringBoot核心原理
基于SpringMVC无配置文件(纯Java)完全注解化+内置tomcat-embed-core实现SpringBoot框架,Main函数启动。
SpringBoot核心快速整合第三方框架原理:Maven继承依赖关系
SpringBoot内嵌入tomcat-embed-core
SpringBoot采用SpringMVC注解版本实现无配置效果
注意:本节课说的不是SpringBoot流程还是SpringBoot核心原理
内置Tomcat容器
Java提供内置Tomcat容器框架,使用Java语言操作Tomcat容器。
案例: 使用Java语言创建一个Tomcat容器
<dependencies><!--Java语言操作tomcat --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>8.5.16</version></dependency><!-- spring-web --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.0.4.RELEASE</version><scope>compile</scope></dependency><!-- spring-mvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.4.RELEASE</version><scope>compile</scope></dependency><!-- tomcat对jsp支持 --><dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jasper</artifactId><version>8.5.16</version></dependency></dependencies>
创建Servet类
public class IndexServet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().print("springboot2.0");}}
创建Tomcat运行
// 端口号private static int PORT = 8080;// 项目名称private static String CONTEXTPATH = "/itmayiedu";public static void main(String[] args) throws LifecycleException {// 创建Tomcat服务器Tomcat tomcatServer = new Tomcat();// 设置Tomcat端口号tomcatServer.setPort(PORT);tomcatServer.getHost().setAutoDeploy(false);// 创建Context上下文StandardContext standardContext = new StandardContext();standardContext.setPath(CONTEXTPATH);standardContext.addLifecycleListener(new FixContextListener());// tomcat容器添加standardContexttomcatServer.getHost().addChild(standardContext);// 创建servlettomcatServer.addServlet(CONTEXTPATH, "IndexServet", new IndexServet());// 添加servleturl映射standardContext.addServletMappingDecoded("/index", "IndexServet");tomcatServer.start();System.out.println("tomcat启动...");tomcatServer.getServer().await();}
SpringMVC(无配置启动)
SpringMVC原理回顾
⑴ 用户发送请求至前端控制器DispatcherServlet
⑵ DispatcherServlet收到请求调用HandlerMapping处理器映射器。
⑶ 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
⑷ DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
⑸ 执行处理器(Controller,也叫后端控制器)。
⑹ Controller执行完成返回ModelAndView
⑺ HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
⑻ DispatcherServlet将ModelAndView传给ViewReslover视图解析器
⑼ ViewReslover解析后返回具体View
⑽ DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
⑾ DispatcherServlet响应用户。
SpringMVC注解启动方式
_DispatcherServlet是Spring MVC的核心,每当应用接受一个HTTP请求,由DispatcherServlet负责将请求分发给应用的其他组件。
在旧版本中,DispatcherServlet之类的servlet一般在web.xml文件中配置,该文件一般会打包进最后的war包种;但是Spring 3引入了注解,我们这节课讲解,如何基于注解配置Spring MVC。
_
Maven依赖
<dependencies><!--Java语言操作tomcat --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>8.5.16</version></dependency><!-- spring-web --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.0.4.RELEASE</version><scope>compile</scope></dependency><!-- spring-mvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.4.RELEASE</version><scope>compile</scope></dependency><!-- tomcat对jsp支持 --><dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jasper</artifactId><version>8.5.16</version></dependency></dependencies>
加载SpringMVCDispatcherServlet
**
AbstractAnnotationConfigDispatcherServletInitializer这个类负责配置DispatcherServlet、初始化Spring MVC容器和Spring容器。getRootConfigClasses()方法用于获取Spring应用容器的配置文件,这里我们给定预先定义的RootConfig.class;getServletConfigClasses负责获取Spring MVC应用容器,这里传入预先定义好的WebConfig.class;getServletMappings()方法负责指定需要由DispatcherServlet映射的路径,这里给定的是”/“,意思是由DispatcherServlet处理所有向该应用发起的请求。
/*** 加载SpringMVCDispatcherServlet** @作者说明 每特教育-余胜军 <br>* @联系方式 qq644064779|www.itmayieducom-蚂蚁课堂<br>*/public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {// 加载根容器protected Class<?>[] getRootConfigClasses() {// TODO Auto-generated method stubreturn new Class[] { RootConfig.class };}// 加载SpringMVC容器protected Class<?>[] getServletConfigClasses() {return new Class[] { WebConfig.class };}// SpringMVCDispatcherServlet 拦截的请求 /protected String[] getServletMappings() {return new String[] { "/" };}}
加载SpringMVC容器
**
正如可以通过多种方式配置DispatcherServlet一样,也可以通过多种方式启动Spring
MVC特性。原来我们一般在xml文件中使用
/*** SpringMVC容器<br>** @EnableWebMvc 开启SpringMVC功能<br>* @Configuration 配置<br>*/@Configuration@EnableWebMvc@ComponentScan("com.itmayiedu.controller")public class WebConfig extends WebMvcConfigurerAdapter {}
RootConfig容器
/*** 根容器 <br>*/@Configuration@ComponentScan(basePackages = "com.itmayiedu")public class RootConfig {}
运行代码
public static void main(String[] args) throws ServletException, LifecycleException {start();}public static void start() throws ServletException, LifecycleException {// 创建Tomcat容器Tomcat tomcatServer = new Tomcat();// 端口号设置tomcatServer.setPort(9090);// 读取项目路径StandardContext ctx = (StandardContext) tomcatServer.addWebapp("/", new File("src/main").getAbsolutePath());// 禁止重新载入ctx.setReloadable(false);// class文件读取地址File additionWebInfClasses = new File("target/classes");// 创建WebRootWebResourceRoot resources = new StandardRoot(ctx);// tomcat内部读取Class执行resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/"));tomcatServer.start();// 异步等待请求执行tomcatServer.getServer().await();}
