SpringBoot筆記

官網:

http://springboot.fun/html

# 打包java

<build>
        <sourceDirectory>${project.basedir}/src</sourceDirectory>
        <resources>
            <resource>
                <directory>resources</directory>
            </resource>
        </resources>
</build>

build 必須包含 sourceDirectory , resources , 才能打包進 jar 包。web

收集到一個比較全的:redis

https://blog.csdn.net/xiaoyu411502/article/details/52474037spring

Idea 中 SpringBoot 方式啓動與 Application 啓動的區別

SpringBoot 啓動, 命令多瞭如下參數 :數據庫

-XX:TieredStopAtLevel=1
-noverify
-Dspring.output.ansi.enabled=always
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=55414
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=localhost
-Dspring.liveBeansView.mbeanDomain
-Dspring.application.admin.enabled=truejson

遇到一個問題. SpringBoot方式啓動沒有錯誤. Application啓動報錯:
Caused by: java.lang.ClassNotFoundException: kotlin.reflect.KotlinReflectionInternalErrorbootstrap

對比發現: Application上添加 -noverify 就能夠了.springboot

調試

  • springboot 傳參,若是參數是空的, 則不寫 =session

  • 代理模式用的方法: Proxy.newProxyInstance

  • 在SpringBoot2.0及Spring 5.0 WebMvcConfigurerAdapter已被廢棄,目前找到解決方案就有兩種

https://blog.csdn.net/lenkvin/article/details/79482205

  • HttpServlet 定義URL
    @ServletComponentScan 配合 @WebServlet ,再使用 HttpServlet

https://www.cnblogs.com/NeverCtrl-C/p/8191920.html

  • Thread.currentThread().contextClassLoader.getResource("").path

三種環境(經過 Thread.currentThread().contextClassLoader.getResource("").protocol 判斷)(.path 和 .file 是相同的)

  • jar : file:/D:/JavaApp/app.shop.java/corp/target/shop-corp-3.0.0.jar!/BOOT-INF/classes!/
  • war : 沒調呢。
  • file : /D:/JavaApp/pzx.java/entity/target/classes/

Jar包的狀況, 能夠經過獲取私有字段: handler.jarFile.name 獲取到: D:\JavaApp\app.shop.java\corp\target\shop-corp-3.0.0.jar

  • bootstrap.yml 早於 applicatoin.yml

http://www.jb51.net/article/139112.htm

SpringMvc 設置消息轉換 設置返回Json的格式。

在全部的消息轉換中找到目標,再修改。

@Autowired
       lateinit var converter: MappingJackson2HttpMessageConverter

        //註冊返回的消息體。
        handerAdapter.messageConverters.filter { it is MappingJackson2HttpMessageConverter }.map { it as MappingJackson2HttpMessageConverter }.forEach {
            it.objectMapper.registerModule(CustomModule())


@Component
class CustomModule() : SimpleModule(PackageVersion.VERSION) {
    init {
        addSerializer(ObjectId::class.java, ObjectIdJsonSerializer());
        addSerializer(LocalDate::class.java, LocalDateJsonSerializer());
        addSerializer(LocalTime::class.java, LocalTimeJsonSerializer());
        addSerializer(LocalDateTime::class.java, LocalDateTimeJsonSerializer());

        addDeserializer(LocalDate::class.java, LocalDateJsonDeserializer())
        addDeserializer(LocalTime::class.java, LocalTimeJsonDeserializer())
        addDeserializer(LocalDateTime::class.java, LocalDateTimeJsonDeserializer())
    }
}

class LocalTimeJsonSerializer : JsonSerializer<LocalTime>() {
    override fun serialize(value: LocalTime?, generator: JsonGenerator, serializers: SerializerProvider) {
        if (value == null) {
            generator.writeNull()
        } else {
            generator.writeString(value.AsString())
        }
    }
}
        }

設置默認字符集

//設置 StringHttpMessageConverter 的字符集
        handerAdapter.messageConverters.filter { it is StringHttpMessageConverter }.map { it as StringHttpMessageConverter }.forEach {
            it.setWriteAcceptCharset(false)
            it.defaultCharset = Charset.forName("utf-8")
        }

設置請求參數與Action函數參數對應關係

var listResolvers = mutableListOf<HandlerMethodArgumentResolver>()
        listResolvers.add(RequestParameterConverter(listOf(ApiParam::class.java)));

        listResolvers.addAll(handerAdapter.argumentResolvers ?: listOf())

        handerAdapter.argumentResolvers = listResolvers;

執行 Test 的時候, Bean 不建立的問題

設置 test resource , 從新 import 會失效.

在 project structure -> module -> 設置 test resources 時,下面有提示. 任何改變都會讓它失效. 因此. 設置 test resource 是最後一步.

classLoader

Thread.currentThread().contextClassLoader 有 私有字段 classes ,表示加載以後的類。 類的加載有過程,在 Test 環境下,發現有的項目在執行Test時,當前項目的類並無徹底加載。

Bean的初始化.

調試中發現, Bean 並無自動建立 .

解決

啓動類上,添加 @Import ,讓它強制執行,可讓該 Bean 強制建立 . 這種方法沒有解決根本問題, 由於有大量的Bean.

找到緣由以下:
SpringBoot項目的Bean裝配默認規則是根據Application類所在的包位置從上往下掃描的。
因此,

  • 把 Test 的啓動類的包名,改成 Bean 的頂級包名便可.
    如: Bean包名: com.abc.def , Test啓動類包名: com.abc 或 com 都可.

  • 或者 @ComponentScan(basePackages=arrayOf("com","org"))
    經測試, 這個方法在 spring-boot 下不行。

  • 使用: @SpringBootApplication(scanBasePackages = arrayOf("nbcp","pandian"))
    scanBasePackages 寫全部啓動加載的包。

見: https://zhidao.baidu.com/question/716351765859826445.html

定時任務總開關

https://my.oschina.net/jspp/blog/1604553
上文說的測試了一下,沒有效果.

@Component open class

對於 @Component 註解的 class ,必定不能是 final , 必須是 open的. 由於Srping會使用 cglib 繼承自該類, 重寫該類的方法.

取消Filter自動註冊

https://www.jianshu.com/p/bf79fdab9c19

取消自動鏈接數據庫:

https://blog.csdn.net/u012240455/article/details/82356075

@EnableAutoConfiguration(exclude = arrayOf(DataSourceAutoConfiguration::class))

新建非Web SpringBoot項目.

http://www.jianshu.com/p/5d4ffe267596
繼承 CommandLineRunner

@SpringBootApplication
class SpringBootConsoleApplication : CommandLineRunner {

    companion object {
        @Throws(Exception::class)
        @JvmStatic
        fun main(args: Array<String>) {
            //disabled banner, don't want to see the spring logo
            val app = SpringApplication(SpringBootConsoleApplication::class.java)
            app.setBannerMode(Banner.Mode.OFF)
            app.run(*args)

        }
    }

    // Put your logic here.
    @Throws(Exception::class)
    override fun run(vararg args: String) {

        fixTagData()

        exit(0)
    }
}

EnableRedisHttpSession

Redis數據庫會有: spring:session:sessions:2519c4cb-4dfb-42c7-9c19-334cc2800e54 的 Hash數據。裏有有如下Field:
maxInactiveInterval
sessionAttr:ValidateCode
lastAccessedTime
sessionAttr:PzxSession
creationTime

Java如何讀出?
讀出字符串容易: var d = rer.jedis(11).jedis.hget("spring:session:sessions:" + id, "sessionAttr:PzxSession")。 
反序列化。 ObjectInputStream( ByteArrayInputStream(d.toByteArray().toMutableList().slice(6).toByteArray())).readObject() 報錯: invalid stream header: EFBFBDEF, 由於: 讀出String的時候就已經錯了。緣由: https://www.cnblogs.com/yanlong300/p/7692595.html
如何讀出二進制流?
var data = rer.jedis(11).jedis.hget (("spring:session:sessions:" + id).toByteArray(), "sessionAttr:PzxSession".toByteArray())
var stream = ObjectInputStream(ByteArrayInputStream(data));
var ent = stream.readObject() as PzxSessionData;

JSessionID 的值 。

JSESSIONID == Base64( request.requestSessionId )

spring:session:sessions:${request.requestSessionId}

spring:session:sessions:${request.requestSessionId}. sessionAttr:${ session.key } == serial ( session.value )
相關文章
相關標籤/搜索