史上最全springboot配置,踩坑,註解,使用手冊(持續更新中)


springboot

春節在家長了幾斤肉,今天開始減肥了(工作了)。19年的第一篇文章,本篇文章將覆蓋springboot所有配置(本人實際工作中所遇到問題以及學習總結),後續將會持續更新!話不多說,直接開始。

詳細配置

注意:本演示全部基於springboot最新版本,現在是2.1.2.RELEASE,並且所有配置將全部使用yaml格式!

如何配置springboot監聽端口?

  1. 通過application.yml指定。(推薦)
server:
  port: 8080

注意:如果使用server.port=0,將使用一個隨機端口,可以控制檯查看。

  1. 指定jvm參數(啓動多個項目調試時推薦使用)
    idea中:Edit Configurations -> VM options
    運行jar命令: java -Dserver.port=8080 app.jar
    [圖片上傳失敗...(image-efdac8-1550224888830)]
  2. 運行java -jar命令時指定
    如: java -jar app.jar --server.port=8080
  3. 通過代碼指定:
@Configuration
public class TomcatConfig {

    @Bean
    @Autowired
    public TomcatWebServerFactoryCustomizer factoryCustomizerAutoConfiguration(Environment environment, ServerProperties serverProperties) {
            serverProperties.setPort(8888);
        return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
    }
}

springboot中如何添加filter

  1. 繼承Filter並且將該類作爲一個bean加入spring容器,使用@Order設置filter順序
@Component
@Order(1000)
public class FirstFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //to do something.
        
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

注意!使用這種方式註冊的filter將攔截所有請求,無法指定攔截url。

  1. 使用FilterRegistrationBean類手動註冊一個filter(推薦)
public class SecondFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //to do something.

        System.out.println("SecondFilter.doFilter");

        filterChain.doFilter(servletRequest, servletResponse);
    }
}
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<SecondFilter> secondFilterFilterRegistrationBean() {
        FilterRegistrationBean<SecondFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new SecondFilter());
        registrationBean.setOrder(10001);

        registrationBean.addUrlPatterns("/**");
        
        return registrationBean;
    }
}
  1. 開啓@WebFilter掃描。
    在啓動類上加上@ServletComponentScan註解,定義filter如下:
@WebFilter(filterName = "ThridFilter", urlPatterns = "/**")
@Order(1002)
public class ThridFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("ThridFilter.doFilter");
        chain.doFilter(req, resp);
    }

}

採坑記錄:該方式只在內置web容器下有效(打jar包),如果使用war包,將失效,有興趣的可以看一看@ServletComponentScan註解說明。

springboot如何添加servlet

  1. 同上類似,使用ServletRegistrationBean
@Bean
public ServletRegistrationBean servletRegistrationBean(){
    return new ServletRegistrationBean(new FooServlet(),"/foo/*");
}

如何配置jpa,數據源?

引入jpa依賴,application.yml中添加數據源信息

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: jason
    url:  jdbc:mysql://localhost:3306/springboot-all-configs?useSSL=false

  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        format_sql: true

採坑記錄1:如果引入jpa但是不定義數據源將會啓動失敗
採坑記錄2:最新版springboot默認mysql驅動爲8.1,自定義參數較多,啓動可能造成數據源初始化失敗,建議降級mysql驅動版本,在pom文件中定義:
[圖片上傳失敗...(image-b8ba24-1550224888830)]

<mysql.version>5.1.47</mysql.version>

生war包運行,部署在weblogic獲取其它servlet容器中

  1. 將tomcat從maven依賴中去掉,啓動類繼承SpringBootServletInitializer
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
@SpringBootApplication
@ServletComponentScan
public class SpringbootAllConfigsApplication extends SpringBootServletInitializer implements WebApplicationInitializer {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootAllConfigsApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringBootApplication.class);
    }
}

最後將pom文件打包方式修改爲war:
<packaging>war</packaging>
使用idea打包:

使用springboot默認生成的項目mvnw.cmd有什麼用

  1. 用作生產環境(linux)上沒有maven環境自動下載maven,打包依賴使用
  2. 沒卵用,直接刪除

如何設置項目的log level

  1. application.yml中指定:
logging:
  level:
    org:
      springframework:
        web: debug
  1. 如果使用logback,添加一個append:
    <logger name="cn.jsbintask.springbootallconfigs.mapper" level="DEBUG"/>

springboot中訪問配置文件中的配置?

  1. 使用@Value註解
@Value("${server.port}")
private int port;
  1. 注入Environment實例,然後獲取值
@RestController
@RequestMapping
public class PropertiesController {
    @Autowired
    private Environment environment;
    
    @GetMapping("/path")
    public String getPath() {
        return environment.getProperty("server.port");
    }
}
  1. 使用ConfigurationProperties註解,定義多個屬性值
    .yml:
cn:
  jsbintask:
    name: jason
    age: 22

.Properties class:

@ConfigurationProperties(prefix = "cn.jsbintask")
@EnableConfigurationProperties
@Component
@Data
public class JsbintaskProperties {
    private String name;
    private int age;
}

使用:

@Autowired
private JsbintaskProperties jsbintaskProperties;

如何指定springboot啓動類

  1. 使用idea指定main class


  2. 在pom文件中指定啓動類
<properties>
    <!-- The main class to start by executing java -jar -->
    <start-class>cn.jsbintask.springbootallconfigs.SpringbootAllConfigsApplication</start-class>
</properties>
  1. 在springboot maven插件中指定:
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>cn.jsbintask.springbootallconfigs</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

application.yml和bootstrap.yml的區別?

  1. bootstrap配置文件先於application.yml配置加載,bootstrap配置屬性一般只在spring cloud獲取配置服務時使用,所以一般如果不使用spring cloud的話,優先使用application.yml.

如何定義rest服務?

  1. 使用@ResponseBody註解配置@RequestMapping註解使用
  2. 使用新註解@RestController配置@XXXMaping(GetMapping)使用。
@RestController
@RequestMapping
public class HelloController {
    
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

springboot中如何處理異常?

  1. 使用RestControllerAdvice新註解以及@ExceptionHanlder處理異常
@RestControllerAdvice
public class ExceptionHandler {
    @org.springframework.web.bind.annotation.ExceptionHandler
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    public String hanld(Exception e) {
        return "error";
    }
}

springboot使用restful服務如何自定錯誤白頁?

當出現錯誤的時候,springboot默認使用一個自定義的錯誤頁面,當使用rest服務時,我們希望自定義返回數據類型。

  1. 實現ErrorController接口:
@RestController
@RequestMapping
public class CustomErrorController implements ErrorController {
    public static final String ERROR_PATH = "/error";

    @RequestMapping(path = ERROR_PATH)
    public String error() {
        return "custom error";
    }

    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }
}

如何定義靜態資源訪問映射(圖片)

  1. 開啓@EnableWebMvc,繼承WebMvcConfigurer類,添加映射
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/");
    }
}

在static文件夾下新建images文件夾,添加一張圖片,訪問 /images/gril.jpg


採坑記錄:上述映射和定位必須一一對應,如改成 registry.addResourceHandler("/static/").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/");**
url則需使用 /static/images/gril.jpg,其它靜態資源同樣使用此方法映射。

springboot項目啓動後如何自動運行指定代碼(如初始化)?

  1. 在main方法後面運行指定service:
public static void main(String[] args) {
    ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringbootAllConfigsApplication.class, args);

    /* way one to init */
    HelloController bean = applicationContext.getBean(HelloController.class);
    bean.init();
}
  1. 使用@EventListener監聽啓動事件
@Component
public class AppReadyListener {
    @EventListener(ApplicationReadyEvent.class)
    public void init() {
        System.out.println("AppReadyListener.init");
    }
}

查看控制檯如下:


  1. 使用@PostConstruct註解
@PostConstruct
public void postConstruct() {
    System.out.println("AppReadyListener.postConstruct");
}
  1. 實現ApplicationRunner接口
@Component
public class AppRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("AppRunner.run");
    }
}

採坑記錄:方法1在war環境中不起作用,方法3可能過早執行(這個bean初始化後就執行),方法4,2爲最佳實踐

如何自定義模板引擎(freemarker)

  1. 添加依賴,修改配置文件:
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
spring:
  freemarker:
    template-loader-path: classpath:/templates/
    check-template-location: true
    charset: UTF-8
    enabled: true
    suffix: .html

接着添加hello.html在templates文件夾下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>templates</title>
</head>
<body>
<h2>hello from jsbintask blog.</h2>
</body>
</html>

添加一個controller,映射到該模板

@Controller
@RequestMapping("/templates")
public class TemplateController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

啓動項目,訪問/templates/hello

springboot如何自定義首頁面,如何自定義視圖

  1. 同上定義模板引擎
  2. 實現WebMvcConfigurer接口,添加視圖映射
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //前面爲訪問路徑( '/'即爲主頁面),後面爲視圖模板位置(如本例配置的爲 templates下)。
        registry.addViewController("/").setViewName("home");
    }
}

配置文件中如何添加數組屬性?

  1. 使用'-'每行一個屬性
key:
  - value1
  - value2
  1. 使用','號隔開每個值
key: value1, value2

使用jpa作數據查詢時,發現實體類的id不能序列化?

這是springboot默認處理了,id不作序列化處理,可以添加如下配置:

@Configuration
public class RepositoryConfig extends RepositoryRestConfigurerAdapter {
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(User.class);
    }
}

採坑記錄:最新版springboot已經默認作了此配置。

springboot修改默認的favicon圖標

  1. 同上,繼承WebMvcConfigure配置類,添加如下配置:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/");

    registry.addResourceHandler("/favicon.ico").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/images/favicon.jpg");
}

springboot的api如何編寫單元測試?

建立在已有的springboot項目上,例如helloController,測試 /hello,編寫測試類:

@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private ServletContext servletContext;

    @Test
    public void test1() throws Exception{
        MvcResult end = mockMvc.perform(requestBuilder("/hello"))
                .andExpect(mvcResult -> {
                    if (mvcResult.getResponse().getStatus() != 200) {
                        throw new RuntimeException("failed.");
                    }
                })
                .andExpect(result -> {
                    if (!result.getResponse().getContentType().contains("json")) {
                        throw new RuntimeException("failed");
                    }
                }).andReturn();

        System.out.println(end);
    }

    private RequestBuilder requestBuilder(String uri) {
        return MockMvcRequestBuilders.get(URI.create(uri)).accept(MediaType.APPLICATION_JSON_UTF8)
                .characterEncoding("UTF-8");
    }
}

其中api看名字便知。

springboot如何爲api配置安全訪問?

  1. 參考系列文章:springsecurity整合springboot從入門到源碼解析

springboot整合各種消息隊列?

  1. 參考系列文章:springboot整合各種消息隊列(持續更新中)

未完待續

今天暫時更新到這,此文章會一直更新! 或者你有感興趣的配置,歡迎留言!

總結

未完待續!
例子源碼:https://github.com/jsbintask22/springboot-all-configs-learning.git,歡迎fork,star學習修改。
本文原創地址:https://jsbintask.cn/2019/02/15/springboot/springboot-all-configs/,轉載請註明出處。
如果你覺得本文對你有用,歡迎關注,分享。這裏只有乾貨!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章