# spring-boot-hello **Repository Path**: hxfl/spring-boot-hello ## Basic Information - **Project Name**: spring-boot-hello - **Description**: spring-boot-hello - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2017-08-08 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #### 目录 + 工具的安装和使用 + 内置Web服务器 + 部署到javaEE容器 + 配置文件 Properties和YAML + 配置文件 多环境配置 + 日志配置 logback和log4j2 + 错误处理/异常处理 + 模板引擎 Thymeleaf + 模板引擎 jsp + 配置 Servlet, Filter, Listener + 配置拦截器 HandlerInterceptor + CORS 跨域请求支持 + 文件上传/下载 + 关系型数据库 JdbcTemplate / JPA + 关系型数据库 事务处理 + 关系型数据库 H2嵌入式数据库的使用 + 多数据源配置 JPA,JDBC + NoSQL数据库 Redis + NoSQL数据库 Mongodb + Caching EhCache + Caching Redis + 异步消息服务 JMS(ActiveMQ) + 异步消息服务 AMQP(RabbitMQ) + 使用HTTP代理 + 发送邮件 + 定时任务 + 使用 Shiro 登录验证和权限管理 + 使用 Spring Session 实现集群 + Redis + 集成 MyBatis + 集成 Druid 和监控配置 + 集成 Swagger + 如何进行远程调试 + 生产准备 启动脚本 + 生产准备 守护进程启动 + 生产准备 HTTP应用监控 工具的安装和使用 --------------- Spring Boot 提供了一个强大的一键式Spring 的集成开发环境,能够单独进行一个Spring 应用的开发,其中: 1. 集中式配置(application.properties)+注解,大大简化了开发流程 2. 内嵌的Tomcat和Jetty容器,可直接打成jar包启动,无需提供Java war包以及繁琐的Web配置 3. 提供了Spring各个插件的基于Maven的pom模板配置,开箱即用,便利无比。 4. 可以在任何你想自动化配置的地方,实现可能 5. 提供更多的企业级开发特性,如何系统监控,健康诊断,权限控制 6. 无冗余代码生成和XML强制配置 7. 提供支持强大的Restfult风格的编码,非常简洁 #### 安装 + 一个称手的文本编辑器(例如Vim、Emacs、Sublime Text)或者IDE(Eclipse、Idea Intellij) + Java环境(JDK 1.7或以上版本) + Maven 3.0+(Eclipse和Idea IntelliJ内置,如果使用IDE并且不使用命令行工具可以不安装) #### 创建应用 创建一个 Maven 工程,引入 spring-boot 组件依赖 UTF-8 1.7 org.springframework.boot spring-boot-starter-parent 1.5.4.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-maven-plugin 然后创建一个程序启动入口类 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class Application { @RequestMapping("/") public String greeting() { return "Hello World!"; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 在IDE中直接直接执行 main 方法,然后访问 http://localhost:8080 即可。 另外可以使用 maven 打包为可执行jar包,然后执行 java -jar xxx.jar。 或者执行 mvn spring-boot:run 运行项目。 #### Spring Boot 推荐的基础 POM 文件 - spring-boot-starter 核心 POM,包含自动配置支持、日志库和对 YAML 配置文件的支持。 - spring-boot-starter-amqp 通过 spring-rabbit 支持 AMQP。 - spring-boot-starter-aop 包含 spring-aop 和 AspectJ 来支持面向切面编程(AOP)。 - spring-boot-starter-batch 支持 Spring Batch,包含 HSQLDB。 - spring-boot-starter-data-jpa 包含 spring-data-jpa、spring-orm 和 Hibernate 来支持 JPA。 - spring-boot-starter-data-mongodb 包含 spring-data-mongodb 来支持 MongoDB。 - spring-boot-starter-data-rest 通过 spring-data-rest-webmvc 支持以 REST 方式暴露 Spring Data 仓库。 - spring-boot-starter-jdbc 支持使用 JDBC 访问数据库。 - spring-boot-starter-security 包含 spring-security。 - spring-boot-starter-test 包含常用的测试所需的依赖,如 JUnit、Hamcrest、Mockito 和 spring-test 等。 - spring-boot-starter-velocity 支持使用 Velocity 作为模板引擎。 - spring-boot-starter-web 支持 Web 应用开发,包含 Tomcat 和 spring-mvc。 - spring-boot-starter-websocket 支持使用 Tomcat 开发 WebSocket 应用。 - spring-boot-starter-ws 支持 Spring Web Services。 - spring-boot-starter-actuator 添加适用于生产环境的功能,如性能指标和监测等功能。 - spring-boot-starter-remote-shell 添加远程 SSH 支持。 - spring-boot-starter-jetty 使用 Jetty 而不是默认的 Tomcat 作为应用服务器。 - spring-boot-starter-log4j 添加 Log4j 的支持。 - spring-boot-starter-logging 使用 Spring Boot 默认的日志框架 Logback。 - spring-boot-starter-tomcat 使用 Spring Boot 默认的 Tomcat 作为应用服务器。 #### 打包运行 + springBoot打包:mvn package + springApp 运行:java -jar myApp --server.port=8080 内置Web服务器 ------------ Spring Boot 其默认是集成web 容器的,启动方式由像普通Java 程序一样,main 函数入口启动。其内置Tomcat 容器或Jetty 容器,具体由配置来决定(默认Tomcat)。 #### 几个常用的配置说明 # 项目 contextPath,一般在正式发布版本中,我们不配置 server.context-path = / # 错误页,指定发生错误时,跳转的URL。请查看 BasicErrorController 源码便知 server.error.path = /error # 服务端口 server.port = 8080 # session 最大超时时间(分钟),默认为30 server.session-timeout = 60 # 该服务绑定IP地址,启动服务器时如本机不是该IP地址则抛出异常启动失败,只有特殊需求的情况下才配置 #server.address=192.168.24.3 #### Tomcat Tomcat 为Spring Boot 的默认容器,下面是几个常用配置 引入Maven依赖: org.springframework.boot spring-boot-starter-tomcat 几个常用配置 # Tomcat 最大线程数,默认为200 server.tomcat.max-threads = 500 # Tomcat 的URI编码 server.tomcat.uri-encoding = UTF-8 # 存放Tomcat的日志、Dump等文件的临时文件夹,默认为系统的tmp文件夹(如:C:\Users\a43sm\AppData\Local\Temp) #server.tomcat.basedir = /tmp # 打开Tomcat 的Access 日志,并可以设置日志格式的方法 #server.tomcat.access-log-enabled = true #server.tomcat.access-log-pattern = # Access log 目录,默认在basedir/logs #server.tomcat.accesslog.directory = # 日志文件目录 #logging.path = /tmp # 日志文件名称,默认为 spring.log #logging.file = spring.log #### Jetty 如果你要选择Jetty,也非常简单,就是把pom 中的tomcat 依赖排除,并加入Jetty 容器的依赖,如下: org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat org.springframework.boot spring-boot-starter-jetty 为了构建一个即是可执行的,又能部署到一个外部容器的war 文件,你需要标记内嵌容器依赖为"provided" 部署到javaEE容器 --------------- 修改启动类,继承 SpringBootServletInitializer 并重写 configure 方法 public class SpringBootSampleApplication extends SpringBootServletInitializer { private static final Logger logger = LoggerFactory.getLogger(SpringBootSampleApplication.class); @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(this.getClass()); } } 修改pom文件中 jar 为 war war 修改 pom,排除 tomcat 插件 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat 配置文件 Properties和YAML ---------------------------- #### 配置文件的生效顺序,会对值进行覆盖 1. @TestPropertySource 注解 2. 命令行参数 3. Java系统属性(System.getProperties()) 4. 操作系统环境变量 5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource 6. 在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量) 7. 在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量) 8. 在@Configuration类上的@PropertySource注解 9. 默认属性(使用SpringApplication.setDefaultProperties指定) #### 配置随机值 info.secret=${random.value} info.number=${random.int} info.bignumber=${random.long} info.number.less.than.ten=${random.int(10)} info.number.in.range=${random.int[1024,65536]} 读取使用注解:@Value(value = "${roncoo.secret}") > 注:出现黄点提示,是要提示配置元数据,可以不配置 #### 属性占位符 当 application.properties 里的值被使用时,它们会被存在的 Environment 过滤,所以你能够引用先前定义的值(比如,系统属性)。 info.name=hostname info.desc=${info.name} is a domain name #### application属性文件,按优先级排序,位置高的将覆盖位置低的 1. 当前目录下的一个 /config 子目录 2. 当前目录 3. 一个 classpath 下的 /config 包 4. classpath 根路径(root) 这个列表是按优先级排序的(列表中位置高的将覆盖位置低的) #### 使用YAML代替Properties > 注意写法:冒号后要加个空格 > YAML的缺点:不能通过 @PropertySource 注解加载。如果需要使用 @PropertySource 注解的方式加载值,那就要使用 properties 文件。 配置文件 多环境配置 ------------------ #### 配置文件 ##### 通过文件名来区分环境 application-{profile}.properties application.properties(默认) app.name = helloworld server.port = 8080 spring.profiles.active = dev application-dev.properties server.port = 8081 application-std.properties server.port = 8082 ##### 在启动程序的时候通过添加 –-spring.profiles.active={profile} 来指定具体使用的配置 java -jar spring-boot-hello.jar -–spring.profiles.active=std Spring Boot 会先加载默认的配置文件,然后使用具体指定的profile 中的配置去覆盖默认配置。 app.name 只存在于默认配置文件 application.properties 中,因为指定环境中不存在同样的配置,所以该值不会被覆盖 server.port 默认为8080,但是我们指定了环境后,将会被覆盖。如果指定std 环境,server.port 则为 8082 spring.profiles.active 默认指定std 环境,如果我们在运行时指定 –-spring.profiles.active=std 那么将应用std 环境,最终 server.port 的值为8082 #### Maven 环境配置 在我们平常的java 开发中,会经常使用到很多配制文件(xxx.properties,xxx.xml),而当我们在本地开发(dev),测试环境测试(test),线上生产使用(product)时,需要不停的去修改这些配制文件,次数一多,相当麻烦。现在,利用 maven 的 profile 插件定义不同的项目构建环境(dev, alpha, beta, pro) 和 filter 插件为不同环境下的配置项注入对应的参数值 功能,我们可实现在编译阶段简单的指定一个参数就能切换配制,提高效率,还不容易出错。 要激活不同的环境打包,我们可以在命令行通过 mvn package –P${profileId} 来让其运行,为了开发便利,默认激活的是dev 开发环境,即开发人员不需要通过命令行手动输入-p 参数也能运行dev 环境的打包。 ##### Maven 的 properties 加载顺序 1. 中的配置 2. pom.xml 中的 3. mvn -Dproperty=value 中定义的 property 相同 key 的 property,以最后一个文件中的配置为最终配置。 ##### 原理 **利用profile 来切换环境** maven profile 可使用操作系统信息,jdk信息,文件是否存在,属性值等作为依据,来激活相应的 profile,也可在编译阶段,通过 mvn 命令加参数 -PprofileId 来手工激活使用对应的 profile **利用filter 实现对资源文件(resouces)过滤** maven filter 可利用指定的 xxx.properties 中对应的 key=value 对资源文件中的 ${key} 进行替换,最终把你的资源文件中的 username=${key} 替换成 username=value ###### 参考示例 spring-boot-hello src/main/resources ${profiles.inactive} application.properties src/main/resources application.properties true org.springframework.boot spring-boot-maven-plugin dev true application-std.properties app-dev src/main/resources/application-dev.properties std application-dev.properties app-std src/main/resources/application-std.properties filter 是在maven 的compile 阶段执行过虑替换的,所以只要触发了编译动作即可,如果像以前一样正常使用发现没有替换,则手工clean 一下工程 日志配置 logback和log4j2 ------------------------ 支持日志框架:Java Util Logging, Log4J2 and Logback,默认是使用 logback 配置方式:默认配置文件配置和引用外部配置文件配置 #### 默认配置文件配置(不建议使用:不够灵活,对log4j2等不够友好) # 日志文件名 logging.file = /tmp/spring.log # 日志级别配置 logging.level.* = INFO logging.level.org.springframework = DEBUG #### 引用外部配置文件 logging.config = classpath:logback.xml #### 参考配置 pom 组件依赖: org.springframework.boot spring-boot-starter-log4j2 日志配置参考: - log4j.xml - log4j2.xml - logback.xml #### 比较 性能比较:Log4J2 和 Logback 都优于 log4j(不推荐使用) 配置方式:Logback 最简洁,spring boot 默认,推荐使用 错误处理/异常处理 ---------------- #### 全局异常处理 > 使用注解:@ControllerAdvice, @ExceptionHandler > 参考实现:exception/(GlobalExceptionHandler) #### 404页面 继承接口:org.springframework.boot.autoconfigure.web.ErrorController > 参考实现:exception/(ErrorController) 模板引擎 Thymeleaf ----------------- Spring boot 在spring默认基础上,自动配置添加了以下特性: 1. 包含了ContentNegotiatingViewResolver和BeanNameViewResolver beans。 2. 对静态资源的支持,包括对WebJars的支持。 3. 自动注册Converter,GenericConverter,Formatter beans。 4. 对HttpMessageConverters的支持。 5. 自动注册MessageCodeResolver。 6. 对静态index.html的支持。 7. 对自定义Favicon的支持。 8. 主动使用ConfigurableWebBindingInitializer bean 引入Maven依赖: org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-logging > 参考示例:controller/HelloThymeleaf > 参考配置:application.properties: spring.thymeleaf.* 模板引擎 jsp ------------ jsp应该尽量避免使用,原因如下: 1. jsp 只能打包为:war 格式,不支持 jar 格式,只能在标准的容器里面跑(tomcat,jetty 都可以) 2. 内嵌的 Jetty 目前不支持 JSPs 3. Undertow 不支持 jsps 4. jsp自定义错误页面不能覆盖 spring boot 默认的错误页面 配置 Servlet, Filter, Listener ----------------------------- #### 方式一 在 SpringBootApplication 使用注解 @ServletComponentScan,然后在 Servlet, Filter, Listener 上增加注解(@WebServlet, @WebFilter, @WebListener)即可。 > 参考实现:HelloServlet, HelloFilter, HelloListener #### 方式二 通过注册 ServletRegistrationBean, FilterRegistrationBean, ServletListenerRegistrationBean 获得控制 > 参考实现:ApplicationConfiguration #### 方式三 通过接口 ServletContextInitializer 直接注册 Servlet, Filter, Listener > 参考实现:Application 配置拦截器 HandlerInterceptor ----------------------------- > 参考示例:config.InterceptorsConfig, interceptors.* CORS 跨域请求支持 ---------------- #### CORS 全局配置 通过重写 WebMvcConfigurerAdapter.addCorsMappings() 方法配置全局的规则 > 参考实现:cors/(CorsConfigurationBean 或 CorsConfiguration) #### CORS 细粒度配置 使用@CrossOrigin注解进行细粒度的配置 > 参考实现:cors/(CorsController) #### 测试 失败:http://127.0.0.1:8080/index $.post('http://localhost:8080/cors/configuration', {name:'world'}, function(response){ console.log(response); }); 成功:http://localhost:8080/index $.post('http://127.0.0.1:8080/cors/configuration', {name:'world'}, function(response){ console.log(response); }); 文件上传/下载 ------------ 引入Maven依赖: commons-fileupload commons-fileupload 1.3.3 > 上传参考:upload/(UploadConfiguration, UploadController, UploadController2) > 下载参考:upload/(DownloadController) 关系型数据库 JdbcTemplate / JPA ------------------------------ 引入Maven依赖: org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-data-jpa jdbcTemplate 对象 sprintBoot 中已经声明好了,可以直接使用,用户只需要声明定义 dataSource 即可 > 参考示例:jdbc/(DataSourceConfiguration, RoleDao) > 参考配置:application.properties:spring.datasource.* > 参考测试:jdbc/JdbcTemplateTest 关系型数据库 事务处理 ------------------- 首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 便可 在Service中,被 @Transactional 注解的方法,将支持事务。如果注解在类上,则整个类的所有方法都默认支持事务。 关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 如果你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例。 如果Spring容器中存在多个 PlatformTransactionManager 实例,并且没有实现接口 TransactionManagementConfigurer 指定默认值,在我们在方法上使用注解 @Transactional 的时候,就必须要用value指定,如果不指定,则会抛出异常。 对于系统需要提供默认事务管理的情况下,实现接口 TransactionManagementConfigurer 指定。 对有的系统,为了避免不必要的问题,在业务中必须要明确指定 @Transactional 的 value 值的情况下。不建议实现接口 TransactionManagementConfigurer,这样控制台会明确抛出异常,开发人员就不会忘记主动指定。 > 参考示例:jdbc/(DataSourceConfiguration, JdbcService, JpaService) > 参考测试:jdbc/(JdbcTemplateTest, JpaServiceTest) #### 隔离级别(Isolation) 隔离级别是指若干个并发的事务之间的隔离程度,与我们开发时候主要相关的场景包括:脏读取、重复读、幻读。 + **DEFAULT** :这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是: READ_COMMITTED 。 + READ_UNCOMMITTED :该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。 + **READ_COMMITTED** :该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。 + REPEATABLE_READ :该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。 + SERIALIZABLE :所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。 #### 传播行为(Propagation) 所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。 + **REQUIRED** :如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 + **SUPPORTS** :如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 + MANDATORY :如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 + REQUIRES_NEW :创建一个新的事务,如果当前存在事务,则把当前事务挂起。 + NOT_SUPPORTED :以非事务方式运行,如果当前存在事务,则把当前事务挂起。 + NEVER :以非事务方式运行,如果当前存在事务,则抛出异常。 + NESTED :如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 REQUIRED 。 关系型数据库 H2嵌入式数据库的使用 ------------------------------- 引入Maven依赖: com.h2database h2 > 参考示例:h2/(H2DataSourceConfiguration, ***) > 参考配置:application.properties:spring.datasource.h2.*, spring.h2.* > 参考测试:h2/(StaffController, JdbcTemplateTest, JpaTemplateTest) 多数据源配置 JPA,JDBC -------------------- > 参考示例:jdbc/*, h2/*, datasource/* > 参考配置:application.properties:spring.datasource.h2.*, spring.datasource.ds1.*, spring.datasource.ds2.* > 参考测试:jdbc/*, h2/*, datasource/* NoSQL数据库 Redis ----------------- 引入Maven依赖: org.springframework.boot spring-boot-starter-data-redis > 参考示例:redis/RedisService* > 参考配置:application.properties:spring.redis.* > 参考测试:redis/(RedisServiceTest, RedisServiceSimpleTest) NoSQL数据库 Mongodb ------------------- #### spring-boot 方式基本配置 引入Maven依赖: org.springframework.boot spring-boot-starter-data-mongodb > 参考示例:mongodb.bean.*, mongo.controller.* > 参考配置:application.properties:spring.data.mongodb.* #### spring-bean 方式及多数据源mongodb 的使用 > 参考示例:mongodb.myconfig.*, mongodb.MongodbTest > 参考配置:application.properties:mongodb.* Caching EhCache --------------- 引入Maven依赖: net.sf.ehcache ehcache 2.10.4 > 参考示例:ehcache/* > 参考配置:application.properties:spring.cache.ehcache.config > 参考测试:ehcache/EhCacheServiceTest #### Cache 注解详解 **@CacheConfig**:主要用于配置该类中会用到的一些共用的缓存配置。在这里 @CacheConfig(cacheNames = "users"):配置了该数据访问对象中返回的内容将存储于名为users的缓存对象中,我们也可以不使用该注解,直接通过 @Cacheable 自己配置缓存集的名字来定义。 **@Cacheable**:配置方法的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。该注解主要有下面几个参数: ***value、cacheNames***:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了 ***key***:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用 SpEL表达式,比如:@Cacheable(key = "#p0"):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档 ***condition***:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存,若做此配置上面的AAA用户就不会被缓存。 ***unless***:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于 condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。 ***keyGenerator***:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现 org.springframework.cache.interceptor.KeyGenerator 接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的 ***cacheManager***:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用 ***cacheResolver***:用于指定使用那个缓存解析器,非必需。需通过 org.springframework.cache.interceptor.CacheResolver 接口来实现自己的缓存解析器,并用该参数指定。 **@CachePut**:配置于函数上,能够根据参数定义条件来进行缓存,它与 @Cacheable不同的是,它每次都会真是调用函数,所以主要用于数据新增和修改操作上。它的参数与@Cacheable类似,具体功能可参考上面对@Cacheable参数的解析 **@CacheEvict**:配置于函数上,通常用在删除方法上,用来从缓存中移除相应数据。除了同 @Cacheable一样的参数之外,它还有下面两个参数: ***allEntries***:非必需,默认为false。当为true时,会移除所有数据 ***beforeInvocation***:非必需,默认为false,会在调用方法之后移除数据。当为true时,会在调用方法之前移除数据。 Caching Redis ------------- > 参考示例:redis/RedisCache* > 参考配置:application.properties:spring.redis.* > 参考测试:redis/RedisCacheServiceTest #### 多缓存配置 CacheManager > 参考配置:redis/RedisCacheConfig, ehcache/EhcacheConfig 注意:需要指定一个 CacheManager 为 @Primary 缓存 异步消息服务 JMS(ActiveMQ) -------------------------- #### 下载安装 到Apache 官方网站下载最新的ActiveMQ 的安装包,并解压到本地目录下,下载链接:http://activemq.apache.org/download.html 如果是32位的机器,就双击win32 目录下的 activemq.bat, 如果是64位机器,则双击win64 目录下的 activemq.bat, 运行。 启动成功!成功之后在浏览器输入 http://127.0.0.1:8161/ 地址,可以看到ActiveMQ 的管理页面,用户名和密码默认都是 admin。 #### 示例 引入Maven依赖: org.springframework.boot spring-boot-starter-activemq org.apache.activemq activemq-pool > 参考示例:jms/* > 参考配置:application.properties:spring.activemq.* > 参考测试:jms/* 注意,消息消费者的类上必须加上 @Component,或者是 @Service, 这样的话,消息消费者类就会被委派给Listener 类,原理类似于使用SessionAwareMessageListener 以及MessageListenerAdapter 来实现消息驱动POJO。 异步消息服务 AMQP(RabbitMQ) --------------------------- #### RabbitMQ 介绍 RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。 ##### 相关概念 通常我们谈到队列服务, 会有三个概念: 发消息者、队列、收消息者,RabbitMQ 在这个基本概念之上, 多做了一层抽象, 在发消息者和 队列之间, 加入了交换器 (Exchange). 这样发消息者和队列就没有直接联系, 转而变成发消息者把消息给交换器, 交换器根据调度策略再把消息再给队列。 ![RabbitMQ](/img/rabbitMq_01.png "rabbitMq_01.png") + 左侧 P 代表 生产者,也就是往 RabbitMQ 发消息的程序。 + 中间即是 RabbitMQ,其中包括了 交换机 和 队列。 + 右侧 C 代表 消费者,也就是往 RabbitMQ 拿消息的程序。 其中比较重要的概念有 4 个,分别为:虚拟主机,交换机,队列,和绑定。 + 虚拟主机:一个虚拟主机持有一组交换机、队列和绑定。为什么需要多个虚拟主机呢?很简单,RabbitMQ当中,用户只能在虚拟主机的粒度进行权限控制。 因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机。每一个RabbitMQ服务器都有一个默认的虚拟主机“/”。 + 交换机:Exchange 用于转发消息,但是它不会做存储 ,如果没有 Queue bind 到 Exchange 的话,它会直接丢弃掉 Producer 发送过来的消息。 这里有一个比较重要的概念:路由键 。消息到交换机的时候,交互机会转发到对应的队列中,那么究竟转发到哪个队列,就要根据该路由键。 + 绑定:也就是交换机需要和队列相绑定,这其中如上图所示,是多对多的关系。 ##### 交换机(Exchange) 交换机的功能主要是接收消息并且转发到绑定的队列,交换机不存储消息,在启用ack模式后,交换机找不到队列会返回错误。交换机有四种类型:Direct, topic, Headers and Fanout + Direct:direct 类型的行为是"先匹配, 再投送". 即在绑定时设定一个 routing_key, 消息的routing_key 匹配时, 才会被交换器投送到绑定的队列中去. + Topic:按规则转发消息(最灵活) + Headers:设置header attribute参数类型的交换机 + Fanout:转发消息到所有绑定队列 #### 下载安装 Windows: http://www.rabbitmq.com/install-windows.html otp_win64_20.1.exe rabbitmq-server-3.6.12.exe RPM: http://www.rabbitmq.com/install-rpm.html #### 示例 引入Maven依赖: org.springframework.boot spring-boot-starter-amqp > 参考示例:amqp/* > 参考配置:application.properties:spring.rabbitmq.* > 参考测试:amqp/* 调用REST服务 如何使用代理 ----------------------- #### HTTP-Proxy-Servlet 引入Maven依赖: org.mitre.dsmiley.httpproxy smiley-http-proxy-servlet 1.7 > 参考示例:proxy/proxyservlet/ProxyServletConfig > 参考配置:application.properties:http.proxy.* #### Jersey代理(略) #### netflix-zuul(略) #### 正向代理 ##### 方法一:设置java 的启动参数 在启动java时增加环境变量参数,比如: -Dhttp.proxyHost=代理ip -Dhttp.proxyPort=3128 -Dhttps.proxyHost=代理ip -Dhttps.proxyPort=3128 ##### 方法二:在java 代码初始化时设置环境变量 System.setProperty("http.proxyHost", "代理ip"); System.setProperty("http.proxyPort", "3128"); System.setProperty("https.proxyHost", "代理ip"); System.setProperty("https.proxyPort", "3128"); ##### 方法三:在java 代码中设置使用代理: URL url = new URL("https://某网址"); Proxy proxy = new Proxy(Proxy.Type.DIRECT.HTTP, new InetSocketAddress("代理ip", 3128)); HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy); ##### 方法四:如果操作系统已经配置好代理,可以直接使用 System.setProperty("java.net.useSystemProxies", "true"); // 当然也可以在启动时增加-Djava.net.useSystemProxies=true // 如果某些网址不需要使用代理,可以单独进行设置,比如: -Dhttp.nonProxyHosts="www.hongxuejing.com|localhost" 发送邮件 ------- 引入Maven依赖: org.springframework.boot spring-boot-starter-mail > 参考示例:mail/* > 参考配置:application.properties:spring.mail.* > 参考测试:mail/* 定时任务 -------- #### 1. 启动类启用定时 在启动类上面加上 **@EnableScheduling** 即可开启定时 #### 2. 参数说明 @Scheduled(cron="*/5 * * * * ?") :0,5,10,...每隔5秒执行一次 @Scheduled(fixedRate = 5000) :上一次开始执行时间点之后5秒再执行 @Scheduled(fixedDelay = 5000) :上一次执行完毕时间点之后5秒再执行 @Scheduled(initialDelay=1000, fixedRate=5000) :第一次延迟1秒后执行,之后按fixedRate 的规则每5秒执行一次 > 参考示例:schedule.* 使用 Shiro 登录验证和权限管理 ---------------------------- #### Shiro 简介 **Shiro 特性** - Authentication(认证):用户身份识别,通常被称为用户“登录” - Authorization(授权):访问控制。比如某个用户是否具有某个操作的使用权限。 - Session Management(会话管理):特定于用户的会话管理,甚至在非web 或 EJB 应用程序。 - Cryptography(加密):在对数据源使用加密算法加密的同时,保证易于使用。 **Filter Chain 定义说明** 1. 一个URL可以配置多个Filter,使用逗号分隔 2. 当设置多个过滤器时,全部验证通过,才视为通过 3. 部分过滤器可指定参数,如 perms, roles 4. 相同路径下,具体的放前面,泛指的(/**)放后面 **Shiro 内置的 FilterChain** - *anon* org.apache.shiro.web.filter.authc.AnonymousFilter - *authc* org.apache.shiro.web.filter.authc.FormAuthenticationFilter - *authcBasic* org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter - *perms* org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter - *port* org.apache.shiro.web.filter.authz.PortFilter - *rest* org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter - *roles* org.apache.shiro.web.filter.authz.RolesAuthorizationFilter - *ssl* org.apache.shiro.web.filter.authz.SslFilter - *user* org.apache.shiro.web.filter.authc.UserFilter - anon: 所有url都都可以匿名访问 - authc: 需要认证才能进行访问 - user: 配置记住我或认证通过可以访问 #### Shiro 使用 引入Maven依赖: org.apache.shiro shiro-spring 1.4.0 org.apache.shiro shiro-ehcache 1.4.0 > 参考代码:shiro.* 使用 Spring Session 实现集群 + Redis ----------------------------------- 引入Maven依赖: org.springframework.boot spring-boot-starter-data-redis org.springframework.session spring-session 1.3.1.RELEASE > 参考示例:springsession/* > 会话查看: 127.0.0.1:6379> keys 'spring:session:*' 1) "spring:session:sessions:d8437897-b54d-44df-8a90-0f75621843c7" 2) "spring:session:sessions:expires:d8437897-b54d-44df-8a90-0f75621843c7" 3) "spring:session:expirations:1508241000000" 127.0.0.1:6379> hkeys spring:session:sessions:d8437897-b54d-44df-8a90-0f75621843c7 1) "lastAccessedTime" 2) "sessionAttr:name" 3) "maxInactiveInterval" 4) "creationTime" 集成 MyBatis ------------ Spring Boot 集成 MyBatis 有两种方式,一种简单的方式就是使用 MyBatis 官方提供的 mybatis-spring-boot-starter。 另外一种方式就是仍然用类似 mybatis-spring 的配置方式,这种方式需要自己写一些代码,但是可以很方便的控制 MyBatis 的各项配置。 #### mybatis-spring-boot-starter 方式 引入Maven依赖: org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.0 添加配置: mybatis.mapper-locations = classpath:mybatis/*.xml mybatis.type-aliases-package = cc.idoone.spring_boot_hello.mybatis.**.entity #### mybatis-spring 方式 自定义配置类:示例 mybatis.h2.MyBatisScanConfiguration, mybatis.h2.MyBatisMapperScannerConfig > 参考示例:mybatis/* > 参考配置:application.properties:spring.datasource.myh2.*, mybatis/*.xml > 参考测试:mybatis/* 集成 Druid 和监控配置 -------------------- #### spring-boot 方式 引入Maven依赖: com.alibaba druid-spring-boot-starter 1.1.3 com.alibaba druid 1.1.3 添加参数配置: > 参考配置:application.properties: spring.datasource.druid.* #### spring-bean 方式 引入Maven依赖: com.alibaba druid 1.1.3 添加 Filter 和 Servlet: > 参考代码:druid.DruidStatFilter, druid.DruidStatViewServlet #### 监控页面效果 http://localhost:8080/druid/index.html ![DruidStatView](/img/druid-statview.png "druid-statview.png") 集成 Swagger ------------ Swagger2 可以轻松的整合到 Spring Boot 中,并与 Spring MVC 程序配合组织出强大 RESTful API 文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个 RESTful API。 #### 添加Swagger2 依赖 在pom.xml 中加入Swagger2 的依赖 io.springfox springfox-swagger2 2.7.0 io.springfox springfox-swagger-ui 2.7.0 #### 创建Swagger2 配置类 在 Application.java 同级包创建 Swagger2 的配置类 Swagger2。 > 参考代码:Swagger2 **注意:在生产环境中应当删除接口文档配置** #### 添加文档内容 > 参考代码:swagger.UserController, mybatis.h2.entity.User #### API文档访问与调试 访问API文档:http://localhost:8080/swagger-ui.html ![SwaggerUI](/img/swagger-ui.png "swagger-ui.png") Swagger2 官方网站:https://swagger.io/ 如何进行远程调试 --------------- #### 简介 所谓的远程调试就是服务端程序运行在一台远程服务器上,我们可以在本地服务端的代码(前提是本地的代码必须和远程服务器运行的代码一致)中设置断点,每当有请求到远程服务器时时能够在本地知道远程服务端的此时的内部状态。 #### 方法 首先,打开 Run/Edit configurations...,点击 + 号,创建一个 Remote 应用。 ![RemoteDebug](/img/idea-remote-debug.png "idea-remote-debug.png") 填写 Name,配置 Host地址(远程服务器地址)和调试端口(选一个未被占用的端口)。然后复制远程调试启动参数,示例配置的端口为5005: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 原项目启动命令为: # java -jar spring-boot-hello.war --server.port=7878 那么此时在启动命令上添加上面获得的参数(Linux 上测试通过): # java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar spring-boot-hello.war --server.port=7878 通过以上步骤已经完成了服务器端参数的添加。下面启动刚才配置的Remote服务,即 RemoteDebug。在启动时候我们会发现此项启动程序只有Debug 启动模式。 启动完成,对需要Debug 的代码打上断点,剩下的操作步骤就是访问远程服务器对应的业务请求,本地就会同步Debug。其余的操作与本地Debug 相同。 #### 方法(WEB 容器 - Tomcat) // 找到Tomcat 下的 bin/startup.sh 文件,在里面添加 // windows // set CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 %CATALINA_OPTS%" // *nix export CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 $CATALINA_OPTS" 生产准备 启动脚本 ---------------- #### clean.sh #!/bin/bash TIME_STAMP=`date +%Y%m%d%H%M` WHO=`whoami` if [ "$WHO" != 'www' ]; then echo 'current user is not www' echo 'exit' exit fi WEBAPPS=/home/www/app PROJECTNAME=mywebapp cd $WEBAPPS/$PROJECTNAME git pull mvn clean package pid=`ps -ef |grep $PROJECTNAME |grep -v "grep" |awk '{print $2}' ` if [ $pid != "" ]; then echo "App is running and pid=$pid" else echo "App is not running." fi #### start.sh #!/bin/bash TIME_STAMP=`date +%Y%m%d%H%M` WHO=`whoami` if [ "$WHO" != 'www' ]; then echo 'current user is not www' echo 'exit' exit fi WEBAPPS=/home/www/app PROJECTNAME=mywebapp cd $WEBAPPS/$PROJECTNAME pid=`ps -ef |grep $PROJECTNAME |grep -v "grep" |awk '{print $2}'` if [ $pid ]; then echo "App is running and pid=$pid" else nohup java -jar $WEBAPPS/$PROJECTNAME/target/$PROJECTNAME-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 & fi #### stop.sh #!/bin/bash TIME_STAMP=`date +%Y%m%d%H%M` WHO=`whoami` if [ "$WHO" != 'www' ]; then echo 'current user is not www' echo 'exit' exit fi WEBAPPS=/home/www/app PROJECTNAME=mywebapp cd $WEBAPPS/$PROJECTNAME pid=`ps -ef |grep $PROJECTNAME |grep -v "grep" |awk '{print $2}' ` if [ $pid ]; then echo "App is running and pid=$pid" kill -9 $pid if [[ $? -eq 0 ]];then echo "stop $PROJECTNAME success" else echo "stop $PROJECTNAME failure" fi fi 生产准备 守护进程启动 -------------------- #### Systemd [Unit] Description=Spring Boot Application [Service] ExecStart=/usr/bin/java -jar location_of_jar_file.jar --spring.config.location=location_of_config.properties --spring.profiles.active=profile User=${your expected user} [Install] WantedBy=multi-user.target #### Supervisord [program:app] command=/usr/bin/java -jar location_of_jar_file.jar --spring.config.location=location_of_config.properties --spring.profiles.active=profile user=${your expected user} autostart=true autorestart=true startsecs=10 startretries=3 生产准备 HTTP应用监控 -------------------- 1. health 应用健康指标 2. info 查看应用信息 3. metrics 应用基本指标 4. trace 基本的HTTP跟踪信息 5. shutdown 关闭当前应用 Spring Boot 监控核心是 spring-boot-starter-actuator 依赖,增加依赖后, Spring Boot 会默认配置一些通用的监控,比如 jvm 监控、类加载、健康监控等。 org.springframework.boot spring-boot-starter-actuator 增加配置(application.properties): # spring-boot-starter-actuator 中安全级别的操作默认工作在安全模式下 # Full authentication is required to access actuator endpoints. # Consider adding Spring Security or set 'management.security.enabled' to false. management.security.enabled = false #### Spring Boot Actuator 所提供的 HTTP 服务 **/health** 这个路径主要是用来统计系统的状况,默认里面目前只有系统状况和磁盘状况。 我们可以通过 http://localhost:8080/health , 统计系统的状况,默认里面目前只有系统状况和磁盘状况。这些检测器都通过 HealthIndicator 接口实现。 **/metrics** 查看应用基本指标 我们可以通过 http://localhost:8080/metrics, 获取当前应用的各类重要度量指标,比如:内存信息、线程信息、垃圾回收信息等。 **/info** 查看应用信息。默认情况下,只会返回一个空的 json 内容。我们可以在 application.properties 配置文件中通过 info 前缀来设置一些属性。 info.author.realname = hemj info.author.nickname = tfjy info.app_name = Hello World info.app_version = 1.0.0 **/actuator** 查看所有EndPoint的列表,需要加入 Spring HATEOAS 支持 **/autoconfig** 查看应用的自动配置的使用情况 **/beans** 可以查看到目前 Spring 里面加载的所有 bean,在生产中感觉没有什么用处,可能在开发中会有一些帮助,方便查看bean 是否被扫描 **/configprops** 查看应用的所有配置属性 **/dump** 查看应用的线程状态信息 **/env** 查看应用的所有环境信息 **/flyway** 查看已经有迁徙路线数据库迁移 **/liquibase** 查看已经有liquibase数据库迁移应用 **/mappings** 查看所有url映射 **/shutdown** (POST) 允许优雅关闭当前应用(默认情况下不启用) **/trace** 监控 http 请求的, 监控每个请求的状况 默认情况下,跟踪信息的存储采用 org.springframework.boot.actuate.trace.InMemoryTraceRepository 实现的内存方式,始终保留最近的 100 条请求记录。 **/docs** 查看文档,需要依赖 spring-boot-actuator-docs **/heapdump** 返回一个gzip压缩 hprof 堆转储文件 **/jolokia** 暴露JMX bean(当jolokia路径) **/logfile** 查看日志文件的内容(如果logging.file或logging.path属性已设置)。支持使用对HTTP范围标头到日志文件的部分恢复内容。 #### 定制监控服务 端点可以在 Spring Boot 配置文件中进行定制。例如: management.context-path = /manage endpoints.mappings.enabled = true endpoints.metrics.enabled = true endpoints.trace.enabled = true endpoints.logfile.enabled = true endpoints.shutdown.enabled = true 默认的端点访问路径是根目录下,我们可以通过修改配置,进行定制。 management.context-path = /manage 此时,我们的访问地址就变成: http://localhost:8080/manage/info 此外,默认监控的接口端口和业务的端口是一致的,我们出于安全性考虑,可以改变端点的访问的端口。 management.port = 9090 我们甚至可以关闭 http 端点。 management.port = -1 > 参考示例:actuator/* 参考 ---- https://docs.spring.io/spring/docs/4.3.5.BUILD-SNAPSHOT/spring-framework-reference/ http://www.cnblogs.com/vinphy/p/4674247.html http://blog.csdn.net/isea533/article/details/50412212 http://www.roncoo.com/course/view/c99516ea604d4053908c1768d6deee3d http://blog.csdn.net/cool__wang/article/category/5910275 http://blog.csdn.net/trigl/article/details/50968079 http://412887952-qq-com.iteye.com/blog/2294952 http://blog.csdn.net/liuchuanhong1/article/category/6332056 http://www.cnblogs.com/ityouknow/p/6120544.html http://www.cnblogs.com/cnblog-long/p/7246038.html http://blog.csdn.net/hguisu/article/category/1114530 http://www.roncoo.com/article/detail/125078 http://www.cnblogs.com/ityouknow/p/6132645.html http://blog.csdn.net/isea533/article/details/50281151 http://blog.csdn.net/bobshute/article/details/53580601