Prefácio
Para uma análise do princípio da inicialização da própria bota da primavera, consulte: http://www.vevb.com/article/141478.htm
O relacionamento de herança do carregador de classe no Spring Boot pode executar a demonstração fornecida abaixo e executá -la em diferentes cenários. Você pode conhecer o relacionamento de herança do carregador de classe dos aplicativos de inicialização da primavera em diferentes cenários.
https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-classloader-context
Existem três situações:
No IDE, a função Run Main é executada diretamente que o carregador de classe do Spring é diretamente SystemClassLoader. Os URLs do carregador de classe contêm todos os frascos e seus próprios alvo/classes
========== URLs de classe de classe de aplicativo de inicialização da primavera ==================
URLs de classe de classe: Sun.misc.launcher$AppClassLoader@2A139A55
Arquivo:/users/hengyunabc/code/java/spring-boot-inside/Demo-ClassLoader-Context/Target/Classes/
Arquivo: /users/hengyunabc/.m2/repository/org/springframework/cloud/spring-cloud-starter/1.1.9.release/spring-cloud-starter-1.1.9.release.jar
Arquivo: /users/hengyunabc/.m2/repository/org/springframework/boot/spring-boot-starter/1.4.7.release/spring-boot-starter-1.4.7.release.jar
...
Correr como jarra de gordura
MVN Clean PackageJava -Jar Target/Demo-ClassLoader-Context-0.0.1-Snapshot.jar
O carregador de classe que executa a função principal do aplicativo é lançado com o fluxo e seu pai é o SystemClassLoader.
========== Classloader Tree ===============
org.springframework.boot.loader.launchedurlclassloadler@1218025C
- Sun.misc.launcher$AppClassloader@6bc7c054
- Sun.misc.launcher$ExtClassloader@85ED7b
E LaunchedURLClassLoader的urls fat jar BOOT-INF/classes!/
========== URLs de classe de classe de aplicativo de inicialização da primavera ==================
URLs de classe de classe: org.springframework.boot.loader.launchedurlclassloader@1218025c
JAR: FILE: /users/hengyunabc/code/java/spring-boot-inside/demo-classloader-context/target/demo-classloader-context-0.0.1-snapshot.jar!/boot-nf/classes!/
JAR: FILE: /users/hengyunabc/code/java/spring-boot-inside/demo-classload-context/target/demo-classloader-context-0.0.1-snapshot.jar! /boot-inf/libs/spring-boot--snapsshot.jar!
jar: file: /users/hengyunabc/code/java/spring-boot-inside/demo-classload-context/target/demo-classloader-context-0.0.1-snapshot.jar! /boot-inf/libs/spring-web-4.9.3.Relazer.jar!
...
Os URLs do SystemClassLoader são demo-classloader-context-0.0.1-SNAPSHOT.jar .
=========== URLs de classe do sistema ======================
URLs de classe de classe: Sun.misc.launcher$AppClassloadner@6bc7c054
Arquivo: /users/hengyunabc/code/java/spring-boot-inside/demo-classloader-context/target/demo-classloader-context-0.0.1-snapshot.jar
Correr como o diretório descomprimido
MVN Clean PackageCD TargetUnzip Demo-ClassLoader-Context-0.0.1-Snapshot.jar -d Democd Demojava org.springframework.boot.loader.propertieslauncher
O carregador de classe que executa a função principal do aplicativo é LaunchedURLClassLoader e seu pai é SystemClassLoader .
========== Classloader Tree ===============
org.springframework.boot.loader.launchedurlclassloadler@4aa298b7
- Sun.misc.launcher$AppClassLoader@2A139A55
- Sun.misc.launcher$ExtClassloader@1b6d3586
Os URLs do LaunchedURLClassLoader são os pacotes de jar abaixo BOOT-INF/classes/ e /BOOT-INF/lib/ no diretório de descompressão.
========== URLs de classe de classe de aplicativo de inicialização da primavera ==================
URLs de classe de classe: org.springframework.boot.loader.launchedurlclassloader@4aa298b7
Arquivo:/users/hengyunabc/code/java/spring-boot-inside/Demo-ClassLoader-Context/Target/Demo/Boot-Inf/Classes/
jar: file: /users/hengyunabc/code/java/spring-boot-inside/demo-classloader-context/target/demo/boot-inf/lib/bcpkix-jdk15on-1.55.jar!
jar: file: /users/hengyunabc/code/java/spring-boot-inside/demo-classloader-context/target/demo/boot-inf/lib/bcprov-jdk15on-1.55.jar!
JAR: FILE: /users/hengyunabc/code/java/spring-boot-inside/demo-classloader-context/target/demo/boot-nf/lib/classmate-1.3.3.jar!
Os URLs do SystemClassLoader têm apenas o diretório atual:
=========== URLs de classe do sistema ======================
URLs de classe de classe: Sun.misc.launcher$AppClassLoader@2A139A55
Arquivo:/users/hengyunabc/code/java/spring-boot-inside/Demo-ClassLoader-Context/Target/Demo/
De fato, existem outras duas maneiras de correr: mvn spring-boot:run e mvn spring-boot:run -Dfork=true , mas raramente é usado e não será discutido separadamente. Se você se sentir interessado, pode correr sozinho.
Resumo da relação de herança do carregador de classe na inicialização da primavera
Quando a função principal é executada no IDE, há apenas um carregador de classe, ou seja, SystemClassLoader
Ao executar como jarte de gordura, existe um carregador lançado cujo pai é SystemClassLoader
Os URLs do lançamento do LankedUrlClassLoader são os frascos em Boot-Inf/Classes e Boot-Inf/Lib em potes de gordura. Os URLs do SystemClassLoader são os próprios potes de gordura.
Ao executar o diretório descompactado, é semelhante ao Fat Jar, mas o URL está na forma de um diretório. O formato do diretório terá melhor compatibilidade.
Versões de inicialização da primavera 1.3. e 1.4.
Na BOOT Spring 1.3.* Versão
A classe do carregador de inicialização da primavera é colocada no frasco de gordura
As mudanças na estrutura de embalagem da bota de mola 1.4 foram introduzidas por este compromisso
https://github.com/spring-projects/spring-boot/commit/87fe0b2adeef85c842c009bfeebac1c84af8a5d7
A intenção original desse compromisso é simplificar o relacionamento de herança do carregador de classe, implementar o Lançado com o Intuitive Parent-Primeiro Padre e, ao mesmo tempo, a estrutura de embalagem está mais próxima do aplicativo de pacote de guerra tradicional.
No entanto, essa mudança causou muitos problemas complexos. Do exposto, analisamos o relacionamento de herança do carregador de classe um pouco tonto.
Alguns impactos da relação de herança atual do carregador de classe
Existem muitos usuários que podem achar que algum código funciona bem no IDE, mas não funciona quando realmente implantado. Muitas vezes é causado pela estrutura do carregador de classe. Aqui estão alguns casos.
Demo.Jar!/Boot-Inf/Classes!/Dessa forma, o URL não funciona
Porque a bota da primavera estende o protocolo JAR padrão, permitindo suportar o jar de várias camadas em jar e diretório no jar. Consulte a análise do princípio de inicialização do aplicativo de inicialização da primavera
Embora haja jar no jar na bota de primavera 1.3, algum código relativamente robusto pode lidar com essa situação, como o próprio Tomcat8 suporta jar no jar.
No entanto, a maior parte do código não suporta vários URLs como demo.jar!/BOOT-INF/classes!/ , Então, na Spring Boot1.4, muitos códigos da biblioteca serão inválidos.
Questões de recursos sob demonstração.jar!/Meta-inf/recursos
Na especificação do servlet 3.0, os aplicativos podem colocar recursos estáticos em meta-inf/recursos, e o contêiner do servlet apoiará a leitura. Mas, a partir dos resultados da herança acima, podemos encontrar um problema:
Isso cria alguns fenômenos estranhos:
Além disso, o exemplo oficial do JSSP de bota de primavera suporta apenas o formato de guerra de embalagem e não suporta o Fat Jar, o que também é causado por isso.
Problemas com o valor de retorno do getResource ("") e getResources ("")
A semântica do GetResource ("") é retornar o primeiro URL dos URLs de classe de classe. Muitas vezes, os usuários pensam que este é o seu próprio diretório de classe, ou o URL do JAR.
Mas, de fato, como o carregador de classe carrega a lista de URLs, ela é aleatória, que está relacionada à implementação de baixo nível do sistema operacional e não pode garantir que a ordem dos URLs seja a mesma. Portanto, o resultado retornado pelo getResource ("") é frequentemente diferente.
No entanto, muitas bibliotecas ou aplicativos dependem desse código para localizar recursos de digitalização, para que não funcionem sob a inicialização da primavera.
Além disso, vale a pena notar que a bota da primavera é executada em três formas diferentes, e os resultados retornados pelo getResources ("" ") também são diferentes. Os usuários podem alterar o código na demonstração sozinhos e imprimir os resultados.
Em suma, não confie nessas duas APIs, é melhor colocar um recurso para localizá -lo sozinho. Ou use diretamente o mecanismo de varredura de recursos fornecido pela própria mola.
Problema de classificação selvagem semelhante a ClassPath*: **-Service.xml
O usuário possui vários módulos de código e os arquivos de configuração de mola *-Service.xml de *-Service.xml são colocados em diferentes módulos.
Se um usuário usa curingas como ClassPath*: **-Service.xml para carregar recursos, é muito provável que ele possa carregar corretamente ao executar no IDE, mas não poderá carregar sob o frasco de gordura.
Você pode ver a análise relevante da própria documentação da Spring:
https://docs.spring.io/spring/docs/4.3.9.release/javadoc-api/org/springframework/core/io/support/pathmatchingResourcepTatternResolver.html
AVISO: Observe que “ClassPath:” Quando combinado com padrões de estilo formigas só funcionará de maneira confiável com pelo menos um diretório raiz antes do início do padrão, a menos que os arquivos de destino reais residam no sistema de arquivos. Isso significa que um padrão como "ClassPath:*. XML" não recuperará arquivos dos arquivos raiz dos jar, mas apenas da raiz dos diretórios expandidos. Isso se origina de uma limitação no método ClassLoader.GetResources () do JDK, que retorna apenas os locais do sistema de arquivos para uma string vazia passada (indicando raízes em potencial a serem pesquisadas). Esta implementação do recursoCepTatterNResolver está tentando mitigar a limitação da pesquisa de raízes JAR através da introdução do URLClassLoader e da avaliação de manifesto "java.class.path"; No entanto, sem garantias de portabilidade.
Ou seja, ao usar o ClassPath* para corresponder a outros pacotes JAR, é preciso haver uma camada de diretório na frente, caso contrário, ele não corresponderá. Isso é causado pela função ClassLoader.GetResources ().
Porque, ao executar no IDE, os outros módulos dos quais o aplicativo depende são geralmente um diretório de classes, portanto, geralmente não há problema.
No entanto, ao executar com o Fat Jar, outros módulos são embalados como uma jarra e colocados em Boot-Inf/Lib, para que a distribuição selvagem falhe neste momento.
Resumir
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.