目录 start
目录 end
|2018-07-21| 码云 | CSDN | OSChina
SpringBoot
一个简化Spring开发的框架,微服务SpringCloud的基础
思考
-
大大降低编程门槛, 但是, 将大量细节隐藏在默认配置中, 需要详细阅读文档和源码才能更好的玩转SpringBoot, 不然到处是坑
SpringBoot启动流程解析
原理才是王道
Spring 是单例模式, 全部使用IOC容器进行管理, 那么怎么处理并发呢,
- 答案是 ? 多线程 然后 ThreadLocal 分别存储了各自的数据, 所以才说, 不能在Controller层 放置属性, 使其具有状态, 从而导致并发问题
- 那么WebSocket服务器, 处理并发会不会有并发问题?
参考教程
系列
开始使用
使用Idea的话就可以直接创建项目 使用别的可以下载zip进行导入 | 官方初始项目构建 下载地址
目录结构最好如下 *Application类要处于所有用了Springboot注解的类的顶级目录, 这样默认才能扫描到
├── config/
├── controller/
├── dao/
├── domain/
├── GraduateApplication.java
├── service/
├── ServletInitializer.java
└── util/
安装SpringBootCLI
- 使用 SDKMAN 进行安装
- 使用git bash运行
curl -s get.sdkman.io | bash
source "/Users/{yourname}/.sdkman/bin/sdkman-init.sh"
根据实际目录去运行- spring --version
- 使用git bash运行
- 官方下载地址 所有版本
测试模块
- [ ] 了解这些测试注解 的作用和使用场景
// 依赖于Springboot环境的测试类的必备注解
@RunWith(SpringRunner.class)
@SpringBootTest
// 使用内存数据库测试
@ComponentScan("com.github.kuagncp") // 如果有类没注入需要手动设置扫面
@RunWith(SpringJUnit4ClassRunner.class)
@DataJpaTest
- 可以使用MockMvc来测试Controller层的代码
- 可以使用MockMvc的SpringSecurity支持来测试安全模块
- 使用 WebIntegraionTest 测试运行中的Web容器
- 启动嵌入式的Servlet容器来进行测试,下断言
- 使用随机端口启动服务器 配置local.server.port=0
- 使用Selenium来测试HTML页面,模拟浏览器的动作,查看系统运行状态
配置文件
配置文件(
application.properties或者yml
)加载顺序 官方文档说明1.当前Jar/War目录下的/config目录
file:./config/
2.当前目录file:./
3.classpath 里的/config目录classpath:/config/
4.classpath 根目录classpath:/
自定义配置文件名就要运行时加参数
java -jar myproject.jar --spring.config.name=myproject
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
- 配置文件的使用
- Spring boot配置文件 application.properties
- SpringBoot常用配置
- 使用Gradle整合SpringBoot+Vue.js-开发调试与打包
自定义配置文件
将应用配置外置并注入成bean
- 配置文件外置
多种配置文件并切换
yml方式
- 单文件
配置文件 application.yml
spring: profiles: active: development # 选用开发模式 --- spring: profiles: development //一系列配置 --- spring: profiles: production //一系列配置
- 或者 多文件放
application-{profile}.yml
yml和Properties结合
- 格式:
application-{profile}.properties
- 将上面的开发部分,发行部分的配置创建两个配置文件
application-dev.properties
和application-prod.properties
- 在主配置文件
application.yml
中指明spring: profiles: active: dev或者是prod
应用配置文件
依赖于
org.springframework.boot:spring-boot-configuration-processor
配置对应的实体类@Data @Component @ConfigurationProperties(prefix = "graduate.main") public class MainConfig { private String delimiter; }
应用配置类
@Configuration @EnableConfigurationProperties(MainConfig.class) public class AutoCustomConfig { }
application.yml
graduate: main: delimiter: ,
Web模块
Lisener
ServletContextListener
@WebListener
public class ApplicationContext implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
System.out.println("Servlet容器初始化");
}
@Override
public void contextDestroyed(ServletContextEvent event) {
System.out.println("Servlet容器销毁");
}
}
上传下载文件
第一种直接上传到应用的webroot或者resources目录下,第二种上传到数据库中,第三种使用ftp。
- Springboot上传文件
- 上传文件有大小限制,使用如下方法进行配置 参考博客
@Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); //单个文件最大 factory.setMaxFileSize("80MB"); //KB,MB // 设置总上传数据总大小 factory.setMaxRequestSize("102400KB"); return factory.createMultipartConfig(); }
错误页面跳转配置
@Configuration public class MvcConfig extends WebMvcConfigurerAdapter { @Bean public EmbeddedServletContainerCustomizer containerCustomizer() { return (container -> { ErrorPage error401Page = new ErrorPage(HttpStatus.FORBIDDEN, "/403.html"); ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html"); ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html"); container.addErrorPages(error401Page, error404Page, error500Page); }); } }
跨域
不同的域名(主机)端口都会导致跨域问题
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 允许任何域名使用
corsConfiguration.addAllowedHeader("*"); // 允许任何头
corsConfiguration.addAllowedMethod("*"); // 允许任何方法(post、get等)
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
}
全局异常处理
- 新建类, 加上注解 ControllerAdvice
- 方法上使用注解
ExceptionHandler(Exception.class)
处理所有异常 - 然后返回值的写法和普通Controller一样, 返回JSON就
ResponseBody
HTTPS的配置
- 签发证书:
keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
server: context-path: /myth ssl: key-store: classpath:keystore.p12 key-store-password: demo1429336 key-store-type: PKCS12 key-alias: tomcat port: 8888 session: timeout: 3000
任意的一个@Configuration注解类里添加
```java @Bean public TomcatEmbeddedServletContainerFactory servletContainerFactory() { TomcatEmbeddedServletContainerFactory factory =
factory.addAdditionalTomcatConnectors(createHttpConnector()); return factory; }new TomcatEmbeddedServletContainerFactory() { @Override protected void postProcessContext(Context context) { //SecurityConstraint必须存在,可以通过其为不同的URL设置不同的重定向策略。 SecurityConstraint securityConstraint = new SecurityConstraint(); securityConstraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); securityConstraint.addCollection(collection); context.addConstraint(securityConstraint); } };
private Connector createHttpConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setSecure(false); connector.setPort(8887);//http端口(这是要新增加的一个端口) connector.setRedirectPort(8888);// https 端口配置文件中tomcat启动的默认端口 return connector; }
- 另一种方式 [参考博客](http://www.cnblogs.com/xinzhao/p/4950689.html)
`方式不一样,没有成功`
```sh
############ 证书颁发机构
# CA机构私钥
openssl genrsa -out ca.key 2048
# CA证书
openssl req -x509 -new -key ca.key -out ca.crt
############ 服务端
# 生成服务端私钥
openssl genrsa -out server.key 2048
# 生成服务端证书请求文件
openssl req -new -key server.key -out server.csr
# 使用CA证书生成服务端证书 关于sha256,默认使用的是sha1,在新版本的chrome中会被认为是不安全的,因为使用了过时的加密算法。
openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt
# 打包服务端的资料为pkcs12格式(非必要,只是换一种格式存储上一步生成的证书) 生成过程中,需要创建访问密码,请记录下来。
openssl pkcs12 -export -in server.crt -inkey server.key -out server.pkcs12
# 生成服务端的keystore(.jks文件, 非必要,Java程序通常使用该格式的证书) 生成过程中,需要创建访问密码,请记录下来。
keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12
# 把ca证书放到keystore中(非必要)
keytool -importcert -keystore server.jks -file ca.crt
线程池
项目部署
生成指定文件
war
- 部署为war必须的类,一般在创建项目时选war就会自动生成,选jar就要手动添加
public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(DemoApplication.class); } }
- maven:
mvn war
即可 mvn package -DskipTests - gradle:
gradle war
然后gradle bootRepackage
即可
jar
- 没有特殊的配置,打包即用
- maven:
mvn package
即可生成可执行的jar - gradle:
gradle jar
然后gradle bootRepackage
也生成可执行jar
- maven:
构建docker镜像
方便监控应用状态,cpu 内存 流量, 官方文档
手动方式
- 先构建得到war或jar,然后根据dockerfile构建一个镜像
FROM frolvlad/alpine-oraclejdk8:slim ADD weixin-1.0.0.war app.war ENTRYPOINT ["java","-jar","/app.war"]