Spring Boot-基本配置

文章目录

Spring Boot Application

###创建FailureAnalyzer
FailureAnalyzer是拦截启动时将异常转化为人类可读消息的一种方法

  • 实现AbstractFailureAnalyzer扩展
  • 注册
      org.springframework.boot.diagnostics.FailureAnalyzer=\
      com.example.ProjectConstraintViolationFailureAnalyzer
    

###自动配置故障排除

  • 通过conditions端点以JSON形式呈现报告
  • 通过查看源代码和Javadoc
    • 查找被调用的类*AutoConfiguration并阅读其源代码。特别注意@Conditional*注释,以了解它们启用了哪些功能以及何时启用。添加–debug到命令行或系统属性-Ddebug以在控制台上获取在您的应用中做出的所有自动配置决策的日志。在启用了执行器的运行应用程序中,查看conditions端点(/actuator/conditions或等效的JMX)以获取相同信息。
    • 查找属于@ConfigurationProperties(例如ServerProperties)的类,然后从中读取可用的外部配置选项。该@ConfigurationProperties注释具有一个name充当前缀外部性能属性。因此,ServerProperties拥有prefix="server"和它的配置性能server.port,server.address以及其他。在启用了执行器的运行应用程序中,查看configprops端点。
    • 寻找对bind方法的使用,以一种轻松的方式Binder将配置值明确地拉出Environment。它通常与前缀一起使用。
    • 查找@Value直接绑定到的注释Environment。
    • 寻找@ConditionalOnExpression注释以响应SpEL表达式来打开或关闭功能,这些注释通常使用从中解析的占位符进行评估Environment。

启动之前自定义环境或ApplicationContext

SpringApplication具有被应用于自定义context或环境的ApplicationListenersApplicationContextInitializers

  • 注册自定义项
    • 在运行之前,调用SpringApplicationaddListenersaddInitializers方法通过对每个应用程序编程
    • 通过设置context.initializer.classescontext.listener.classes属性,以声明方式针对每个应用程序
    • 通过添加META-INF/spring.factories和打包jar文件声明性地对于所有应用程序,这些文件被应用程序用作库
  • 自定义环境
      org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
    
  • 从类路径中加载YAML配置文件
      public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
      
          private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
      
          @Override
          public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
              Resource path = new ClassPathResource("com/example/myapp/config.yml");
              PropertySource<?> propertySource = loadYaml(path);
              environment.getPropertySources().addLast(propertySource);
          }
      
          private PropertySource<?> loadYaml(Resource path) {
              if (!path.exists()) {
                  throw new IllegalArgumentException("Resource " + path + " does not exist");
              }
              try {
                  return this.loader.load("custom-resource", path).get(0);
              }
              catch (IOException ex) {
                  throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
              }
          }
      
      }
    

建立ApplicationContext层次结构

使用ApplicationBuilder类创建ApplicationContext层次结构

创建非Web应用程序

使用SpringApplication功能,根据是否需要Web Application确定更改ApplicationContext
##属性和配置

在构建时自动扩展属性

使用现有的构建配置自动扩展它们,而不是对项目的构建配置中指定某些属性进行硬编码

  • 使用Maven自动扩展属性
    • 如果使用spring-boot-starter-parent,使用@..@占位符引用
      app.encoding=@project.build.sourceEncoding@
      app.java.version=@java.version@
    
    pom.xml build元素中配置
      <resources>
          <resource>
              <directory>src/main/resources</directory>
              <filtering>true</filtering>
          </resource>
      </resources>
    
    此外需要在plugins元素中配置
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-resources-plugin</artifactId>
          <version>2.7</version>
          <configuration>
              <delimiters>
                  <delimiter>@</delimiter>
              </delimiters>
              <useDefaultDelimiters>false</useDefaultDelimiters>
          </configuration>
      </plugin>
    
  • 使用Gradle扩展属性

SpringApplication外部配置

在配置文件中添加

   spring.main.web-application-type=none
   spring.main.banner-mode=off
  • 外部配置定义的属性会覆盖JavaAPI中得值
    new SpringApplicationBuilder()
        .bannerMode(Banner.Mode.OFF)
        .sources(demo.MyApp.class)
        .run(args);
    
    外部配置
        spring.main.sources=com.acme.Config,com.acme.ExtraConfig
        spring.main.banner-mode=console
    
    实际应用中使用外部配置
    ###更改应用程序外部属性的位置
    默认情况下,不同源的属性以环境定义的顺序添加到Spring中
  • 修改位置
    • 添加@PropertySource
    • 配置属性spring.config.name,默认为application作为文件得根路径
    • 配置属性spring.config.location:要加载的文件,可以通过系统属性、环境变量或命令行覆盖

使用命令行参数

如在命令行上配置--port=9000而不是--server.port=9000

  • 使用占位符
      server.port=${port:8080}
    

对外部属性使用YAML

YAML是JSON的超级,用于分层格式存储外部属性

    spring:
        application:
            name: cruncher
        datasource:
            driverClassName: com.mysql.jdbc.Driver
            url: jdbc:mysql://localhost/test
    server:
        port: 9000

创建application.yaml放置类路径的根目录下

  • 配置
      spring.application.name=cruncher
      spring.datasource.driver-class-name=com.mysql.jdbc.Driver
      spring.datasource.url=jdbc:mysql://localhost/test
      server.port=9000
    

设置Active Spring Profiles

使用-D指定打包环境

     java -jar -D spring.profiles.active=production demo-0.0.1-SNAPSHOT.jar

在配置文件中指定

    spring.profiles.active=production

根据环境更改配置

YAML文件实际上是由---行分割的文档序列,每个文档分别解析为展平图

  • 如果YAML文档包含spring.profiles密钥,则将配置文件值(以逗号分隔的配置文件列表)输入到Spring Environment.acceptsProfiles()方法中。如果这些配置文件中的任何一个处于活动状态,那么该文档将包含在最终合并中(否则,它不会包含在此文档中)
      server:
          port: 9000
      ---
      spring:
          profiles: development
      server:
          port: 9001
      ---
      spring:
          profiles: production
      server:
          port: 0
    

外部属性的内置选项

Spring Boot在运行时将外部属性绑定到应用程序中。使用@ConfigurationProperties@Value以及偶尔使用Binder绑定值

嵌入式Web服务器

###使用其他服务器

  • 默认服务器
    • spring-boot-starter-web默认包含tomcat
    • webflux默认包含reactor-netty
  • 配除Tomcat
      <properties>
          <servlet-api.version>3.1.0</servlet-api.version>
      </properties>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
          <exclusions>
              <!-- Exclude the Tomcat dependency -->
              <exclusion>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-tomcat</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
      <!-- Use Jetty instead -->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-jetty</artifactId>
      </dependency>
    

禁用web服务器

    spring.main.web-application-type=none

更改Http端口

默认8080,配置server.port修改端口,server.port=0扫描可用端口

在运行时发现HTTP端口

从日志输出或ServletWebServerApplicationContext通过其WebServer端口访问服务器正在运行的端口

  • 通过@LocalServerPort将实际端口注入到测试中
      @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
      public class MyWebIntegrationTests {
      
          @Autowired
          ServletWebServerApplicationContext server;
      
          @LocalServerPort
          int port;
      
          // ...
      
      }
    

启动Http影响压缩

   server.compression.enabled=true
  • 通过server.compression.min-response-size设置压缩字节,默认至少2018个字节
  • 通过server.compression.mime-types设置内容类型,如text/html

配置SSL

    server.port=8443
    server.ssl.key-store=classpath:keystore.jks
    server.ssl.key-store-password=secret
    server.ssl.key-password=another-secret

配置Http/2

使用erver.http2.enabled配置启用http/2支持

配置Web服务器

  • 适用于带有spring-boot-starter-web的Tomcat
      @Component
      public class MyTomcatWebServerCustomizer
              implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
      
          @Override
          public void customize(TomcatServletWebServerFactory factory) {
              // customize the factory here
          }
      }
    
ServerServlet stackReactive stack
TomcatTomcatServletWebServerFactoryTomcatReactiveWebServerFactory
JettyJettyServletWebServerFactoryJettyReactiveWebServerFactory
UndertowUndertowServletWebServerFactoryUndertowReactiveWebServerFactory
ReactorN/ANettyReactiveWebServerFactory

###将Servlet、Filters、Listeners添加到应用程序

  • 两种方法
    • 使用Spring Bean添加Servlet、Filters、Listeners
    • 使用类路径扫描
  • 禁用Servlet或过滤器的注册
       @Bean
       public FilterRegistrationBean registration(MyFilter filter) {
           FilterRegistrationBean registration = new FilterRegistrationBean(filter);
           registration.setEnabled(false);
           return registration;
       }
    

配置访问日志

    server.tomcat.basedir=my-tomcat
    server.tomcat.accesslog.enabled=true
    server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms)

在前端代理服务器后面运行

如果代理添加常规X-Forwarded-ForX-Forwarded-Proto标头(大多数代理服务器都这样做),则绝对链接应正确呈现,只要application.properties中server.forward-headers-strategy将设置为NATIVEFRAMEWORK

  • 自定义Tomcat代理
    • 配置headerforwarded
        server.tomcat.remote-ip-header=x-your-remote-ip-header
        server.tomcat.protocol-header=x-your-protocol-header
      
    • 添加自定义匹配
        server.tomcat.internal-proxies=192\\.168\\.\\d{1,3}\\.\\d{1,3}
      

使用Tomcat启用Multiple Connectors

向TomcatServletWebServerFactory添加org.apache.catalina.connector.Connector允许多个Connectors,包括HTTP和HTTPS连接器

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        tomcat.addAdditionalTomcatConnectors(createSslConnector());
        return tomcat;
    }
    
    private Connector createSslConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
        try {
            File keystore = new ClassPathResource("keystore").getFile();
            File truststore = new ClassPathResource("keystore").getFile();
            connector.setScheme("https");
            connector.setSecure(true);
            connector.setPort(8443);
            protocol.setSSLEnabled(true);
            protocol.setKeystoreFile(keystore.getAbsolutePath());
            protocol.setKeystorePass("changeit");
            protocol.setTruststoreFile(truststore.getAbsolutePath());
            protocol.setTruststorePass("changeit");
            protocol.setKeyAlias("apitester");
            return connector;
        }
        catch (IOException ex) {
            throw new IllegalStateException("can't access keystore: [" + "keystore"
                    + "] or truststore: [" + "keystore" + "]", ex);
        }
    }

使用Tomcat LegacyCookieProcessor

默认情况,嵌入式Tomcat不支持Cookie格式的"Version 0",会出现错误

    java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value

考虑更新为服务Cookie规范或者将Tomcat配置为使用LegacyCookieProcessor

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
        return (factory) -> factory
                .addContextCustomizers((context) -> context.setCookieProcessor(new LegacyCookieProcessor()));
    }

启用Tomcat的MBean注册表

默认是禁用的,减少Tomcat内容占用

    server.tomcat.mbeanregistry.enabled=true

使用Undertow启用多个监听器

    @Bean
    public UndertowServletWebServerFactory servletWebServerFactory() {
        UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
        factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
    
            @Override
            public void customize(Builder builder) {
                builder.addHttpListener(8080, "0.0.0.0");
            }
    
        });
        return factory;
    }

@ServerEndPoint创建WebSocket端点

在Spring Boot应用程序中使用的嵌入式容器使用@ServerEndpoint

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

##Spring MVC

编写JOSN REST服务

只要Jackson2在类路径上,SpringBoot中的所有@RestController默认都是JSON响应

    @RestController
    public class MyController {
    
        @RequestMapping("/thing")
        public MyThing thing() {
                return new MyThing();
        }
    
    }

编写XML REST服务

  • 添加依赖
      <dependency>
          <groupId>com.fasterxml.jackson.dataformat</groupId>
          <artifactId>jackson-dataformat-xml</artifactId>
      </dependency>
    
  • 如果无法使用Jackson的XML扩展可以使用JAXB,添加@XmlRootElement注释
      @XmlRootElement
      public class MyThing {
          private String name;
          // .. getters and setters
      }
    
    较新的Java版本添加依赖
      <dependency>
          <groupId>org.glassfish.jaxb</groupId>
          <artifactId>jaxb-runtime</artifactId>
      </dependency>
    

自定义Jackson ObjectMapper

Spring MVC使用HttpMessageConverters协商HTTP交换中的内容转换,如果已添加Jackson,已获得所提供的默认转换器Jackson2ObjectMapperBuilder

自定义@ResponseBody渲染

Spring通过HttpMessageConverters呈现@ResponseBody的响应

处理分段文件上传

java.servlet.http.PartAPI支持上传文件,默认情况Spring Boot用单个请求配置为多个文件

  • 作为参数接收时,MulitipartFile支持

关闭Spring MVC DDispatcherServlet

默认情况下,所有内容从根目录提供。关闭默认需要自定义

  • 映射地址
      spring.mvc.servlet.path=/acme
    

关闭默认的MVC配置

@Configuration上添加@EnableWebMVC注解

自定义ViewResolvers

  • ViewResolvers是Spring MVC的核心组件,将@Controller视图名称转为实际的View实现
  • 主要用于UI应用程序而不是REST风格的服务
  • WebMvcAutoConfiguration添加的ViewResolver
    • 名为“defaultViewResolver”的InternalResourceViewResolver.查找可以通过使用DefaultServlet渲染的物理资源(包括静态资源和JSP页面)
    • 名为“beanNameViewResolver"的BeanNameViewResolver.是视图解析链的有用成员,可以拾取与被解析View名称相同的所有bean
    • 当当时类型为视图 View类型的bean时添加名称”viewResolver“的ContentNegotiatingViewResolver.是"master"解析器,委派给其他所有的解析器,并查找与客户端发送的"Accept"头部信息匹配的内容
    • 使用Themeleaf,需要名为”thymeleafViewResolver“的ThymeleafViewResolver.通过在视图名称前后加上前缀和后缀查找资源。默认前缀为"classpath:/templates",后缀为".html"

使用Spring Security进行测试

Spring Security提供了以特定身份运行测试的支持

    @Test
    @WithMockUser(roles="ADMIN")
    public void requestProtectedUrlWithUser() throws Exception {
        mvc
            .perform(get("/"))
            ...
    }

Jersey

使用Spring Security保护Jersey endpoints

ResourceConfig设置jersey.config.server.response.setStatusOverSendError设置为true

    @Component
    public class JerseyConfig extends ResourceConfig {
    
        public JerseyConfig() {
            register(Endpoint.class);
            setProperties(Collections.singletonMap("jersey.config.server.response.setStatusOverSendError", true));
        }
    
    }

与另一个Web框架使用Jersey

首先通过配置spring.jersey.type应用程序属性配置为filter,以将Jersey配置为使用过滤器而不是Servlet,其次,配置ResourceConfig请求以转发可能导致404的请求

    @Component
    public class JerseyConfig extends ResourceConfig {
    
        public JerseyConfig() {
            register(Endpoint.class);
            property(ServletProperties.FILTER_FORWARD_ON_404, true);
        }
    
    }

Http Clients

配置RestTemplate使用代理

    static class ProxyCustomizer implements RestTemplateCustomizer {
    
        @Override
        public void customize(RestTemplate restTemplate) {
            HttpHost proxy = new HttpHost("proxy.example.com");
            HttpClient httpClient = HttpClientBuilder.create().setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {
    
                @Override
                public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context)
                        throws HttpException {
                    if (target.getHostName().equals("192.168.0.5")) {
                        return null;
                    }
                    return super.determineProxy(target, request, context);
                }
    
            }).build();
            restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
        }
    
    }

配置使用基于Reactor Netty 的WebClient的TcpClient

当Reactor Netty在类路径上时,将自动配置基于Reactor Netty 的WebClient。
要自定义客户端对网络连接的处理,需提供ClientHttpConnectorBean

    @Bean
    ClientHttpConnector clientHttpConnector(ReactorResourceFactory resourceFactory) {
        TcpClient tcpClient = TcpClient.create(resourceFactory.getConnectionProvider())
                .runOn(resourceFactory.getLoopResources()).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60000)
                .doOnConnected((connection) -> connection.addHandlerLast(new ReadTimeoutHandler(60)));
        return new ReactorClientHttpConnector(HttpClient.from(tcpClient));
    }

Logging

添加依赖项会添加日志记录

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

设置级别

    logging.level.org.springframework.web=DEBUG
    logging.level.org.hibernate=ERROR

文件位置

    logging.file.name = ****

默认情况下使用logback.xml配置

配置Logback for Logging

自定义配置需要在application.properties添加标准的Logback配置文件

  • 标准logback.xml配置
    <?xml version="1.0" encoding="UTF-8"?>
      <configuration>
          <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
          <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
          <root level="INFO">
              <appender-ref ref="CONSOLE" />
          </root>
          <logger name="org.springframework.web" level="DEBUG"/>
      </configuration>
    
    • System属性
      • ${PID}: 当前进程ID
      • ${LOG_FILE}: 是否在Boot的外部配置中设置的logging.file.path
      • ${LOG_PATH}: 是否在Boot的外部配置种设置的logging.file.path
      • ${LOG_EXCEPTION_CONVERSTON_WORD}:是否在Boot的外部配置中设置的logging.exception-conversion-word
      • ${ROLLING_FILE_NAME_PATTERN}:是否在Boot的外部配置中设置的logging.pattern.rolling-file-name
配置仅文件输出的Logback

禁用控制台日志记录并且仅将输入写入文件,需要导入file-appender.xml但不导入conso-appender.xmllogback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
        <configuration>
            <include resource="org/springframework/boot/logging/logback/defaults.xml" />
            <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
            <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
            <root level="INFO">
                <appender-ref ref="FILE" />
            </root>
        </configuration>

添加logging.file.name到application.properties

logging.file.name=myapplication.log

配置Log4j进行日志记录

如果Spring Boot在类路径中,支持Log4j2进行日志记录配置。

  • 使用Starters组装依赖项,必须排除Logback,然后改为 include log4j2.
  • 不使用Starters,除了log4j2之外,需要提供spring-jcl
  • 在Maven种设置启动器
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
          <exclusions>
              <exclusion>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-logging</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-log4j2</artifactId>
      </dependency>
    
使用YAML或JSON配置Log4j2
  • 依赖项及文件格式

    格式依赖项文件名
    YAMLcom.fasterxml.jackson.core:jackson-databind+
    com.fasterxml.jackson.dataformat:jackson-dataformat-yaml
    log4j2.yaml
    log4j2.yml
    JSONcom.fasterxml.jackson.core:jackson-databindlog4j3.json
    log4j2.json

Data存取

配置自定义DataSource

  • 在Bean种定义数据源
   @Bean
   @ConfigurationProperties(prefix="app.datasource")
   public DataSource dataSource() {
       return new FancyDataSource();
   }
  • 通过设置属性定义数据源
    app.datasource.url=jdbc:h2:mem:mydb
    app.datasource.username=sa
    app.datasource.pool-size=30
  • 使用DataSourceBuilder创建数据源
    @Bean
    @ConfigurationProperties("app.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
  • 通过设置属性定义JDBC数据源
    app.datasource.url=jdbc:mysql://localhost/test
    app.datasource.username=dbuser
    app.datasource.password=dbpass
    app.datasource.pool-size=30

为了兼容Hikari没有url属性但有jdbcUrl属性

app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.maximum-pool-size=30
  • 创建具有DataSourceBuilderHikarDataSource
    @Bean
    @ConfigurationProperties("app.datasource")
    public HikariDataSource dataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

配置两个DataSource

配置多个DataSource,必须将其中一个DataSource实例标记为@Primary

  • 创建自定义DataSource,自动配置将退出。与自定配置在主数据源上提供功能完全相同功能集示例:
      @Bean
      @Primary
      @ConfigurationProperties("app.datasource.first")
      public DataSourceProperties firstDataSourceProperties() {
          return new DataSourceProperties();
      }
      
      @Bean
      @Primary
      @ConfigurationProperties("app.datasource.first.configuration")
      public HikariDataSource firstDataSource() {
          return firstDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
      }
      
      @Bean
      @ConfigurationProperties("app.datasource.second")
      public BasicDataSource secondDataSource() {
          return DataSourceBuilder.create().type(BasicDataSource.class).build();
      }
    

多个数据源必须进行高级定制。

    app.datasource.first.url=jdbc:mysql://localhost/first
    app.datasource.first.username=dbuser
    app.datasource.first.password=dbpass
    app.datasource.first.configuration.maximum-pool-size=30
    
    app.datasource.second.url=jdbc:mysql://localhost/second
    app.datasource.second.username=dbuser
    app.datasource.second.password=dbpass
    app.datasource.second.max-total=30

将相同概念应用于辅助服务器DataSource

    app.datasource.first.url=jdbc:mysql://localhost/first
    app.datasource.first.username=dbuser
    app.datasource.first.password=dbpass
    app.datasource.first.configuration.maximum-pool-size=30
    
    app.datasource.second.url=jdbc:mysql://localhost/second
    app.datasource.second.username=dbuser
    app.datasource.second.password=dbpass
    app.datasource.second.max-total=30

使用Spring Data Repositories

Spring Data 可以创建各种类型的@Reoisutory接口的实现.只要@Repositories和@EnableAutoConfiguration包含在同一包中,SpringBoot就会处理所有操作

将@Entity定义与Spring 配置分开

Spring Boot会用过@EnableAutoConfiguration发现的内容尝试猜测定义的@Entity的位置。使用@EntityScan注释获取更多操作

    @Configuration(proxyBeanMethods = false)
    @EnableAutoConfiguration
    @EntityScan(basePackageClasses=City.class)
    public class Application {
    
    }

配置JPA属性

Spring Data Jpa提供了一些vendor-independent配置选项(例如用于SQL日志记录),并且Spring Boot将这些选项作为了外部配置属性公开

配置Hibernate命名策略

Hibernate使用两种命名策略将名称从对象模型映射到相应的数据库名称。通过设置pring.jpa.hibernate.naming.physical-strategyspring.jpa.hibernate.naming.implicit-strategy属性配置物理和隐式策略实现的标准类名。

如果对应Bean可用,Hibernate自动配置为使用它们

默认Spring Boot使用配置物理命名策略SpringPhysicalNamingStrategy

  • 使用Hibernate5默认设置
      spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    
    或配置Bean
      @Bean
      public PhysicalNamingStrategy physicalNamingStrategy() {
          return new PhysicalNamingStrategyStandardImpl();
      }
    

配置Hibernate二级缓存

  • 使用JCache,添加org.hibernate:hibernate-jcache依赖,添加HibernatePropertiesCustomizerBean
      @Configuration(proxyBeanMethods = false)
      public class HibernateSecondLevelCacheExample {
      
          @Bean
          public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(JCacheCacheManager cacheManager) {
              return (properties) -> properties.put(ConfigSettings.CACHE_MANAGER, cacheManager.getCacheManager());
          }
      
      }
    

在Hibernate组件中使用依赖注入

默认情况Spring Boot通过实现注册一个使用BeanFactory的BeanContainer实现以实现转换器和实体监听器可以使用常规依赖项注入。

也可以通过注册HibernatePropertiesCustomizer删除或更改hinernate。resources.beans.container属性禁用或调整此行为

使用自定义EntityManagerFactory

添加entityManagerFactory@Bean完全控制EntityManagerFactory的配置

使用两个EntityManager

即使默认设置EntityManagerFactory工作正常,也需要定义一个新的配置,否则,该类型的第二个bean的存在将关闭默认值

  • 直接从Spring ORM操作
      // add two data sources configured as above
      
      @Bean
      public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(
              EntityManagerFactoryBuilder builder) {
          return builder
                  .dataSource(customerDataSource())
                  .packages(Customer.class)
                  .persistenceUnit("customers")
                  .build();
      }
      
      @Bean
      public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
              EntityManagerFactoryBuilder builder) {
          return builder
                  .dataSource(orderDataSource())
                  .packages(Order.class)
                  .persistenceUnit("orders")
                  .build();
      }
    
  • 使用Spring Data,配置@EnableJpaRepositories
       @Configuration(proxyBeanMethods = false)
       @EnableJpaRepositories(basePackageClasses = Customer.class,
               entityManagerFactoryRef = "customerEntityManagerFactory")
       public class CustomerConfiguration {
           ...
       }
       
       @Configuration(proxyBeanMethods = false)
       @EnableJpaRepositories(basePackageClasses = Order.class,
               entityManagerFactoryRef = "orderEntityManagerFactory")
       public class OrderConfiguration {
           ...
       }
    

使用传统persistence.xml文件

默认情况下,Spring Boot不会搜索或使用persitence.xml文件,需要自定义LocalEntityManagerFactoryBean并在其中设置持久性单元名称

使用Spring Data Jpa和Mongo Repositories

Spring Data Jpa和Spring Data Mongo默认会自动创建Repository实现。需要使用@EnableJpaRepositories@EnableMongoRepositories注释兵提供Repository接口的位置

定制Spring Data的支持

spring.data.web命名空间,Spring Data REST 使用spring.data.rest命名空间

将Spring Data Repository 公开为Rest Endpoints

Spring Boot 公开了属性用于自定义RepositoryRestConfiguration。使用RepositoryRestConfigurer Bean提供其他定制

配置JPA使用的组件

配置JPA使用的组件之前,确保在JPA之前初始化该组件。

  • 自定义配置组件
      /**
       * {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
       * {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
       */
      @Component
      static class ElasticsearchEntityManagerFactoryDependsOnPostProcessor
              extends EntityManagerFactoryDependsOnPostProcessor {
      
          ElasticsearchEntityManagerFactoryDependsOnPostProcessor() {
              super("elasticsearchClient");
          }
      
      }
    

Database初始化

使用不同的方式初始化SQL数据库,具体取决于堆栈是什么

使用JPA初始化数据库

JPA具有用于DDL生成的功能,可以将其设置为在启动时针对数据库运行。通过外部属性控制

  • spring.data.generate-ddl:布尔值,打开过关闭该功能,并且与供应商无关
  • spring.jpa.hibernate.ddl-auto:枚举,是一种Hibernate功能,更精细的控制行为

使用Hibernate初始化数据库

设置spring.jpa.hibernate.ddl-auto:nonevalidateupodatecreatecreate-drop。默认create-drop

初始化DataBase

Spring Boot 自动创建schema(DDL脚本)并对其和DataSource进行初始化。从根路径加载sql对应文件

初始化Spring Batch DataSource

Spring Batch随大多数流行的数据库平台预包装了SQL初始化脚本,并可以检测数据库类型且在启动时执行这些脚本。

  • 启动
      spring.batch.initialize-schema =always
    

使用高级数据库迁移工具

在启动时执行Flyway数据库迁移

添加org.flywaydb:flyway-core依赖

在启动时执行Liquibase数据库迁移

添加org.liquibase:liquibase-core

Messaging

禁用Transacted JMS Session

如果JMS代理不支持事务处理会话,必须完全禁用事务支持

  • 禁用事务性会话
      @Bean
      public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(
              ConnectionFactory connectionFactory,
              DefaultJmsListenerContainerFactoryConfigurer configurer) {
          DefaultJmsListenerContainerFactory listenerFactory =
                  new DefaultJmsListenerContainerFactory();
          configurer.configure(listenerFactory, connectionFactory);
          listenerFactory.setTransactionManager(null);
          listenerFactory.setSessionTransacted(false);
          return listenerFactory;
      }
    

Batch Applications

在启动时执行Spring Batch Jobs

在上下文中的某个位置添加@EnableBatchProcessing可以启用Spring Batch配置

Actuator

更改Actuator Endpoints的Http端口或地址

在独立应用程序中,Actuator HTTP端口默认于主HTTP端口相同,设置management.server.port属性使应用程序在其他端口上侦听。要侦听完全不同的网络地址,设置属性managerment.server.address

自定义"whitelabel"错误页面

通常使用View解析error名称或@Controller处理/error路径

Sanitize sensible values

Spring Boot会对一些密钥使用明智的默认设置,如:对以单词password、secret、key或token结尾的密钥进行处理,也可以改用正则表达式,如将*credentials.*将单词credentials保留为键一部分的任何键

Security

关闭Spring Boot Security配置

如果定义了一个@ConfigurationWebSecurityConfigurerAdapter,将默认关闭Spring Boot默认的Webapp安全设置

更改UserDetailsService并添加用户账户

如果提供了AuthenticationManagerAuthenticationProviderUserDetailsService类型的@Bean,默认的InMemoryUserDetailsManager类型的@Bean不创建

在代理服务器上运行时启用HTTPS

对于所有应用程序而言,确保所有主要端点仅可通过HTTPS进行访问都是一项重要的工作。

  • 标准行为为由某些请求标头(x-forwarded-forx-forwarded-proto)的存在或不存在决定
  • 添加属性打开valve
      server.tomcat.remote-ip-header=x-forwarded-for
      server.tomcat.protocol-header=x-forwarded-proto
    
  • Spring Security配置为要求所有请求使用安全通道
      @Configuration(proxyBeanMethods = false)
      public class SslWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
      
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              // Customize the application security
              http.requiresChannel().anyRequest().requiresSecure();
          }
      
      }
    

热更新

重新加载静态内容

推荐使用spring-boot-devtools,因为提供了开发时的一些功能,如对快速应用程序重新启动和LiveReload的支持以及何止的开发时配置(例如模板缓存)

重新加载默认,无需重新启动容器

  • Thymeleaf模板
    • 设置spring.themeleaf,cache = false
  • FreeMarker模板
    • 设置spring.freemarker.cache = false
  • Groovy模板
    • 设置spring.groovy.template.cache=false

快速启用重启

spring-boot-devtools模块包括对应用程序自动重启的支持

重新加载Java类而不重新启动容器

干净重新加载更改的Java类

Build

生成构建信息

  • 使用Maven生成构建信息,为build-info目标添加执行
      <build>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
                  <version>2.2.1.RELEASE</version>
                  <executions>
                      <execution>
                          <goals>
                              <goal>build-info</goal>
                          </goals>
                      </execution>
                  </executions>
              </plugin>
          </plugins>
      </build>
    

生成Git信息

Maven用户,添加与配置创建生成git.properties

    <build>
        <plugins>
            <plugin>
                <groupId>pl.project13.maven</groupId>
                <artifactId>git-commit-id-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

自定义依赖版本

添加自定义版本号

    <properties>
        <slf4j.version>1.7.5<slf4j.version>
    </properties>

使用Maven创建可执行JAR

spring-boot-maven-plugin用于创建可执行的"fat"jar。

  • 声明插件
      <build>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
              </plugin>
          </plugins>
      </build>
    
  • 不适用父POM,也可以使用该插件,但是必须添加
      <build>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
                  <version>2.2.1.RELEASE</version>
                  <executions>
                      <execution>
                          <goals>
                              <goal>repackage</goal>
                          </goals>
                      </execution>
                  </executions>
              </plugin>
          </plugins>
      </build>
    

使用SpringBoot应用程序作为依赖项

Spring Boot默认不作为依赖项,通常方法是将公用的代码以到单独的模块中,然后作为依赖项

  • 为了产生两个工作,一个用作依赖项,一个可以执行,必须指定分类器.
      <build>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
                  <configuration>
                      <classifier>exec</classifier>
                  </configuration>
              </plugin>
          </plugins>
      </build>
    

运行可执行Jar时提取特定的库

可执行Jar中的大多数嵌套库不需要解压即可运行,但是某些库会有问题。

  • 指示使用Maven插件将JRuby标记为解包
      <build>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
                  <configuration>
                      <requiresUnpack>
                          <dependency>
                              <groupId>org.jruby</groupId>
                              <artifactId>jruby-complete</artifactId>
                          </dependency>
                      </requiresUnpack>
                  </configuration>
              </plugin>
          </plugins>
      </build>
    

创建带有排除项的不可执行的Jar

  • 排除application.yml
       <build>
           <plugins>
               <plugin>
                   <groupId>org.springframework.boot</groupId>
                   <artifactId>spring-boot-maven-plugin</artifactId>
               </plugin>
               <plugin>
                   <artifactId>maven-jar-plugin</artifactId>
                   <executions>
                       <execution>
                           <id>lib</id>
                           <phase>package</phase>
                           <goals>
                               <goal>jar</goal>
                           </goals>
                           <configuration>
                               <classifier>lib</classifier>
                               <excludes>
                                   <exclude>application.yml</exclude>
                               </excludes>
                           </configuration>
                       </execution>
                   </executions>
               </plugin>
           </plugins>
       </build> 
    

远程调试以Maven开头的Spring Boot应用程序

将远程调试器附加到使用Maven启动的Spring Boot应用程序,可以使用maven plugin的jvmArguments属性

在不使用Ant的情况下从Ant构建可执行存档spring-boot-antlib

  • 使用spring-boot-antlib模块操作
    • 将类和资源文件打包在BOOT-INF/classes目录中
    • BOOT-INF/lib jar或BOOT-INF/lib war的嵌套目录中添加运行时依赖项。注意:不要压缩存档中的条目
    • BOOT-INF/lib-provided jar或WEB-INF/lib-provided war 的嵌套目录中添加(嵌入式容器)依赖项。注意:不要压缩存档中的条目。
    • 添加spring-boot-loader添加到存档的根目录
      = 使用适当的启动器作为清单中的Main-Class属性,并指定其所需的其他属性作为清单条目
  • And构建归档文档
      <target name="build" depends="compile">
          <jar destfile="target/${ant.project.name}-${spring-boot.version}.jar" compress="false">
              <mappedresources>
                  <fileset dir="target/classes" />
                  <globmapper from="*" to="BOOT-INF/classes/*"/>
              </mappedresources>
              <mappedresources>
                  <fileset dir="src/main/resources" erroronmissingdir="false"/>
                  <globmapper from="*" to="BOOT-INF/classes/*"/>
              </mappedresources>
              <mappedresources>
                  <fileset dir="${lib.dir}/runtime" />
                  <globmapper from="*" to="BOOT-INF/lib/*"/>
              </mappedresources>
              <zipfileset src="${lib.dir}/loader/spring-boot-loader-jar-${spring-boot.version}.jar" />
              <manifest>
                  <attribute name="Main-Class" value="org.springframework.boot.loader.JarLauncher" />
                  <attribute name="Start-Class" value="${start-class}" />
              </manifest>
          </jar>
      </target>
    

传统部署

创建可部署的War包

  • 第一步:是提供一个SpringBootServletInitializer子类并覆盖configure方法.这样是利用了Spring Framework的Servlet3.0支持,并允许在由Servlet容器启动应用程序时对其进行配置.

    通常。主类更新为集成SpringBootServletInitializer
    @SpringBootApplication
    public class Application extends SpringBootServletInitializer {
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(Application.class);
        }
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
  • 第二步:更新构建配置,以使项目生成war文件而不是jar文件
      <packaging>war</packaging>
    
  • 第三步:确保嵌入式servlet容器不干扰war文件所部署到的servlet容器
      <dependencies>
          <!-- … -->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-tomcat</artifactId>
              <scope>provided</scope>
          </dependency>
          <!-- … -->
      </dependencies>
    

将现有应用程序转换为Spring Boot

  • 转换过程
    • 扩展SpringBootServletIntializer并添加@SpringBootApplication注释创建war包
        @SpringBootApplication
        public class Application extends SpringBootServletInitializer {
        
            @Override
            protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
                // Customize the application or call application.sources(...) to add sources
                // Since our example is itself a @Configuration class (via @SpringBootApplication)
                // we actually don't need to override this method.
                return application;
            }
        
        }
    
    • 将静态资源移动到根目录/public/static/resources/META-INF/resources
    • ServletServletRegistration类型的@Bean安装在容器中,等同于web.xml中的和
    • 创建FilterFilterRegistrationBean类型的@Bean,等同于和
    • 通过@ImportResource引入Application xml文件
    • Application中添加main方法使其变为可执行文件
  • 应用程序类别
    • 没有web.xml的Servlet 3.0+应用程序
    • 带有web.xml的应用程序
    • 具有上下文层次结构的应用程序
    • 没有上下文层次结构的应用程序

j将War部署到WebLogic

将Spring Boot应用程序部署到WebLogic,必须确保servlet初始化程序直接实现WebApplicationInitializer

  • WebLogic的典型初始化程序
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
    import org.springframework.web.WebApplicationInitializer;
    
    @SpringBootApplication
    public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
    
    }
    

使用Logback,需要设置WebLogic首选打包版本,而不是服务器预先安装的版本。

  • WEB-INF/weblogic.xml配置
      <?xml version="1.0" encoding="UTF-8"?>
      <wls:weblogic-web-app
          xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
              https://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
              http://xmlns.oracle.com/weblogic/weblogic-web-app
              https://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
          <wls:container-descriptor>
              <wls:prefer-application-packages>
                  <wls:package-name>org.slf4j</wls:package-name>
              </wls:prefer-application-packages>
          </wls:container-descriptor>
      </wls:weblogic-web-app>
    

使用Jedis代替Lettuce

默认情况,SpringBoot Stater(spring-boot-starter-data-redis)使用Lettuce。需要排除该依赖,使用Jedis

   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId>
       <exclusions>
           <exclusion>
               <groupId>io.lettuce</groupId>
               <artifactId>lettuce-core</artifactId>
           </exclusion>
       </exclusions>
   </dependency>
   <dependency>
       <groupId>redis.clients</groupId>
       <artifactId>jedis</artifactId>
   </dependency>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值