머리말
이 기사는 Spring Boot 1.3의 작동 원리를 분석합니다. 스프링 부츠 1.4. 그 후, 포장 구조가 변경되는 것으로 밝혀졌고 Boot-Inf 디렉토리가 추가되었지만 기본 원칙은 변경되지 않았습니다.
Spring Boot 1.4.*에서 클래스 로더의 변경 사항은 다음을 참조하십시오. http://www.vevb.com/article/141479.htm
스프링 부츠 빠른 시작
Spring Boot에서 매우 매력적인 기능은 응용 프로그램을 Jar/War에 직접 포장 할 수 있으며 다른 웹 서버를 구성하지 않고도이 JAR/War를 직접 시작할 수 있다는 것입니다.
전에 Spring Boot를 사용하지 않은 경우 아래 데모를 통해 경험할 수 있습니다.
다음은 Spring Boot Project를 시작하는 방법을 보여주는 예입니다.
git clone [email protected] : hengyunabc/spring-boot-demo.gitmvn spring-boot-demojava -jar target/demo-0.0.1-snapshot.jar
사용 된 IDE가 Spring ST 또는 아이디어 인 경우 마법사를 통해 스프링 부팅 프로젝트를 만들 수 있습니다.
공식 튜토리얼을 참조 할 수도 있습니다.
http://docs.spring.io/spring-boot/docs/current-snapshot/reference/htmlsingle/#getting-started-first-application
Spring Boot에 대한 두 가지 질문
처음으로 Spring Boot에 연락하기 시작하면 일반적으로 이러한 질문이 있습니다.
Spring Boot가 어떻게 수행되는지 분석해 봅시다.
단일 항아리로 포장 될 때 스프링 부츠가 시작되는 방법
Maven이 포장 된 후 두 개의 JAR 파일이 생성됩니다.
Demo-0.0.1-snapshot.jardemo-0.0.1-snapshot.jar.original
여기서 Demo-0.1-snapshot.jar.original은 기본 Maven-Jar-Plugin 생성 패키지입니다.
Demo-0.0.1-snapshot.jar는 Spring Boot Maven 플러그인에서 생성 된 JAR 패키지로 응용 프로그램 종속성 및 스프링 부트 관련 클래스가 포함되어 있습니다. 이하는 뚱뚱한 항아리라고합니다.
먼저, Spring Boot가 준비한 패키지의 디렉토리 구조를 확인해 봅시다 (중요하지 않은 경우 생략) :
├ ─) mfest.mf├à 정전 .mf├à 정전. application.properties.) com temoapplication.class├à 정상 ├퀴 ─ aopalliance-1.0.jar│ ├ ├ ├ └ └ └ └ └ └ └ └ └ └ 용고 ├ └ └ └ └ └ é ├ └ ├ ├ ├ ├ ├ ├ ├ ├ ├ ├ ├ ├ ├ ├ ├ ├ ├치;;; Roader는 executivearchivelauncher.class ├ ├ ├ ├얼사를 execut 엘라 런처 .class ├ ├ ├커.class ├ ├ ├ 착수 ├ 들어 뻗은 엘라 lclassloader.class ├ ├ ├ ├ ├ ├얼용으로 메인 메드로드 런너.
이 내용을 차례로 살펴 보겠습니다.
매니페스트 .mf
선언문 : 1.0start-class : com.example.springbootdemoapplicationimementation-vendor-id : com.examplesspring-boot-version : 1.3.0. ReleaseCreated-by : Apache Maven 3.3.3build-jdk : 1.8.0_60 vendor : pivotal sofeak, inc.mothass : org.springframework.boot.loader.jarlauncher
메인 클래스가 org.springframework.boot.loader.jarlauncher임을 알 수 있습니다.
com.example.springbootdemoapplication 인 start-class도 있습니다. 이것은 우리가 적용하는 주요 기능입니다.
@SpringBootApplicationPublic Class SpringBootDemoApplication {public static void main (String [] args) {springApplication.run (springbootdemoApplication.class, args); }} com/예제 디렉토리
다음은 응용 프로그램의 .class 파일입니다.
lib 디렉토리
다음은 응용 프로그램이 의존하는 JAR 패키지 파일입니다.
예를 들어, 스프링 콩, 스프링 -MVC 및 기타 항아리.
org/springframework/boot/loader 디렉토리
다음은 스프링 부트 로더의 .class 파일입니다.
아카이브 개념
Spring Boot에서는 아카이브의 개념이 추상화됩니다.
아카이브는 항아리 (Jarfilearchive) 또는 파일 디렉토리 (ExplodedArchive) 일 수 있습니다. Spring Boot에 의해 추상화 된 통합 액세스 리소스의 계층으로 이해할 수 있습니다.
위의 Demo-0.0.1-snapshot.jar는 아카이브이며, Demo-0.0.1-snapshot.jar의 /lib 디렉토리 아래의 각 JAR 패키지도 아카이브입니다.
공개 초록 클래스 아카이브 {public Abstract URL geturl (); 공개 문자열 getMainClass (); 공개 초록 컬렉션 <ETCTE> getEntries (); 공개 초록 목록 <Archive> getNestEdArchives (EntryFilter 필터);아카이브에는 다음과 같은 자체 URL이 있음을 알 수 있습니다.
JAR : 파일 : /tmp/target/demo-0.1-snapshot.jar!/
getNestEdArchives 함수도 있습니다. 실제로 Demo-0.0.1-snapshot.jar/lib에서 항아리의 아카이브 목록을 반환합니다. 그들의 URL은 다음과 같습니다.
JAR : 파일 : /tmp/target/demo-0.0.1-snapshot.jar! /lib/aopalliance-1.0.jarjar : file : /tmp/target/demo-0.0.1-snapshot.jar! /lib/spring-beans-4.2.3.release.jar
Jarlauncher
Manifest.mf에서 주요 함수는 Jarlauncher임을 알 수 있습니다. 아래의 워크 플로를 분석하겠습니다.
Jarlauncher 클래스의 상속 구조는 다음과 같습니다.
Class Jarlauncher는 ExecutiveRearvivelAuncherClass ExecutiveRearchivelauncher 확장 런처를 확장합니다
Demo-0.0.1-snapshot.jar로 아카이브를 만듭니다.
Jarlauncher는 먼저 자신이있는 위치, 즉 Demo-0.0.1-snapshot.jar의 경로를 찾은 다음 아카이브를 만듭니다.
다음 코드는 클래스에서 로딩 위치를 찾는 방법에 대한 트릭을 보여줍니다.
보호 된 최종 아카이브 createarchive ()는 예외를 {ProtectionDomain ProtectionAmain = getClass (). getProtectionDomain (); CodeSource CodesOURCE = ProtectionDomain.getCodeSource (); uri location = (codesource == null? null : codesource.getLocation (). touri ()); 문자열 path = (location == null? null : location.getSchemescificPart ()); if (path == NULL) {New ImperalStateException ( "코드 소스 아카이브를 결정할 수 없음"); } 파일 루트 = 새 파일 (경로); if (! root.exists ()) {Throw New ImperalStateException ( " + root에서 코드 소스 아카이브를 결정할 수 없습니다); } return (root.isdirectory ()? new ExplodErarchive (root) : new Jarfilearchive (root));} Lib/ 아래에서 항아리를 가져 와서 발사 된 두르 클래스 로더를 만듭니다
Jarlauncher가 아카이브를 생성 한 후 GetNestEdArchives 함수를 사용하여 Demo-0.0.1-snapshot.jar/lib 아래에서 모든 JAR 파일을 얻고 목록으로 만듭니다.
위에서 언급했듯이 아카이브에는 자체 URL이 있습니다.
이 아카이브 URL을 얻은 후에는 URL [] 배열을 얻고이를 사용하여 사용자 정의 클래스 로더를 구성합니다 : 런치어 클래스 로더.
클래스 로더를 작성한 후 Manifest.mf, 즉 com.example.springbootdemoapplication에서 start-class를 읽은 다음 새 스레드를 작성하여 응용 프로그램의 기본 기능을 시작하십시오.
/*** 아카이브 파일과 완전히 구성된 클래스 로더가 주어지면 응용 프로그램을 시작하십시오. */Protected void unlain (String [] args, String mainclass, classloader classloader)은 예외 {runnable runner = createmainmethodrunner (mainclass, args, classloader); 스레드 러너 스레드 = 새 스레드 (러너); runnerthread.setContextClassLoader (클래스 로더); runnerthread.setName (ride.currentThread (). getName ()); runnerthread.start ();}/*** 응용 프로그램을 시작하는 데 사용되는 {@code mainmethodrunner}를 만듭니다. */보호 된 Runnable CreateMainMethodRunner (String MainClass, String [] Args, ClassLoader ClassLoader) 예외 {class <?> runnerClass = classloader.loadClass (runner_class); 생성자 <?> 생성자 = RunnerClass.getConstructor (String.class, String []. class); 리턴 (runnable) 생성자 .newinstance (Mainclass, Args);} 런치 어 릴 클래스 로더
LaunchedUrlClassLoader와 일반 UrlClassLoader의 차이점은 아카이브에서 .class를로드 할 수있는 기능을 제공한다는 것입니다.
아카이브에서 제공하는 getentries 기능을 결합하면 아카이브에서 리소스를 얻을 수 있습니다. 물론 내부에는 여전히 많은 세부 사항이 있으므로 아래에 설명하겠습니다.
스프링 부팅 애플리케이션 시작 프로세스 요약
이것을 본 후 Spring Boot 응용 프로그램의 시작 프로세스를 요약 할 수 있습니다.
스프링 부트 로더의 세부 사항
코드 주소 : https://github.com/spring-projects/spring-boot/master/spring-boot-tools/spring-boot-loader
Jarfile URL의 확장
스프링 부츠는 뚱뚱한 병으로 시작할 수 있습니다. 가장 중요한 것은 JAR에서 JAR의 로딩 방법을 구현한다는 것입니다.
JDK의 원래 Jarfile URL의 정의는 여기에서 찾을 수 있습니다.
http://docs.oracle.com/javase/7/docs/api/java/net/jarurlconnection.html
원래 Jarfile URL은 다음과 같습니다.
JAR : 파일 : /tmp/target/demo-0.1-snapshot.jar!/
JAR 패키지의 리소스 URL :
다음과 같이 코드를 복사하십시오. jar : file : /tmp/target/demo-0.0.1-snapshot.jar! /com/example/springbootdemoapplication.class
Jar의 리소스의 경우 정의가 '!/'로 분리됩니다. 원래 Jarfile URL은 하나만 지원합니다!/'.
Spring Boot는이 프로토콜을 확장하여 다중 '!/'를 지원하여 Directory Resources의 Jar, Jar에서 Jar를 나타낼 수 있습니다.
예를 들어, 다음 URL은 Spring-Beans-4.2.3.3.release.jar를 Demo-0.0.1-snapshot.jar : jar를 나타냅니다.
다음과 같이 코드를 복사하십시오. jar : file : /tmp/target/demo-0.0.1-snapshot.jar! /lib/spring-beans-4.2.3.release.jar!/meta-inf/manifest.mf
사용자 정의 UrlstreamHandler, Jarfile 및 JarurlConnection을 확장하십시오
URL을 구성 할 때는 처리기를 전달할 수 있으며 JDK에는 기본 처리기 클래스가 제공됩니다. 응용 프로그램은 사용자 정의 URL을 처리하기 위해 핸들러 자체를 등록 할 수 있습니다.
public url (문자열 프로토콜, 문자열 호스트, int 포트, 문자열 파일, urlstreamhandler handler)
참조 :
https://docs.oracle.com/javase/8/docs/api/java/net/url.html#url-java.lang.string-java.lang.string-int-java.lang-sstring-
Spring Boot는 사용자 정의 핸들러 클래스를 등록하여 항아리에서 여러 항아리의 논리를 처리합니다.
이 핸들러는 Softreference를 사용하여 모든 열린 jarfiles를 캐시합니다.
다음과 같은 URL을 처리 할 때 '!/'분리기는 순환됩니다. 상단 층에서 시작하여 먼저 Jarfile Demo-0.0.1-SnapShot.jar를 구성한 다음 Jarfile Spring-Beans-4.2.3. Release.jar를 구성한 다음 JarurlConnection을 구분하여 Manifest.MF를 구성합니다.
다음과 같이 코드를 복사하십시오. jar : file : /tmp/target/demo-0.0.1-snapshot.jar! /lib/spring-beans-4.2.3.release.jar!/meta-inf/manifest.mf
//org.springframework.boot.loader.jar.HandlerPublic 클래스 핸들러 확장 urlStreamHandler {private static final String exparator = "!/"; Private STATIC SOFTREFERNE <MAP <FILE, JARFILE >> ROOTFILECACHE; @override protected urlconnection openconnection (url url)은 ioexception {if (this.jarfile! = null) {return new JarurlConnection (url, this.jarfile); } try {return new JarurlConnection (url, getRootJarfileFromUrl (url)); } catch (예외) {return OpeningFallBackConnection (url, ex); }} public jarfile getRootJarfileFromUrl (url url)은 ioException {String spec = url.getFile (); int separatorIndex = spec.indexof (분리기); if (separatorIndex == -1) {Throw New Ollformedurlexception ( "Jar URL이 포함되어 있지 않습니다!/ 분리기"); } 문자열 이름 = Spec.SubString (0, sepleatorIndex); getRootJarfile (이름)을 반환합니다. } 클래스 로더가 리소스를 읽는 방법
클래스 로더에 필요한 능력은 무엇입니까?
해당 API는 다음과 같습니다.
public url findResource (문자열 이름) public inputStream getResourceasstream (문자열 이름)
위에서 언급했듯이 Spring Boot Constructs를 시작하면 URL [] 배열을 전달합니다. 배열은 LIB 디렉토리 아래 항아리의 URL입니다.
JDK 또는 ClassLoader는 URL의 내용을 읽는 방법을 어떻게 알 수 있습니까?
실제로 프로세스는 다음과 같습니다.
마지막 호출은 jarurlconnection의 getInputStream () 함수입니다.
//org.springframework.boot.loader.jar.jarurlConnection @Override public inputStream getInputStream ()가 IoException {connect (); if (th리 } retract this.jarentRyData.getInputStream (); }URL에서 마지막으로 URL의 내용을 읽는 것까지 전체 프로세스는 매우 복잡합니다. 요약하자 :
여기에는 많은 세부 사항이 있으며 몇 가지 중요한 포인트 만 표시됩니다.
그렇다면 UrlClassLoader는 어떻게 GetResource를 제공합니까?
UrlClassLoader를 구성 할 때는 URL [] 배열 매개 변수가 있으며이 배열을 사용하여 UrlClassPath를 구성합니다.
urlclasspath ucp = new urlclasspath (urls);
UrlClassPath에서는 모든 URL에 대한 로더가 구성되며 GetResource를 얻을 때 이러한 로더에서 하나씩 가져 오려고합니다.
취득이 성공하면 아래와 같이 리소스로 포장됩니다.
자원 getResource (최종 문자열 이름, 부울 점검) {최종 URL URL; try {url = new url (base, parseutil.encodepath (이름, false)); } catch (marlormedurlexception e) {새로운 불법 행위 exception ( "name"); } 최종 URLConnection UC; try {if (check) {urlclasspath.check (url); } uc = url.openConnection (); inputStream in = uc.getInputStream (); if (jarurlconnection의 uc 인스턴스) { / * 서둘러 항아리 파일을 닫을 수 있도록 jar 파일을 기억해야합니다. */ jarurlconnection juc = (JarurlConnection) uc; jarfile = jarloader.checkjar (juc.getjarfile ()); }} catch (예외 e) {return null; } return new resource () {public String getName () {return name; } public url geturl () {return url; } public url getCodeSourceUrl () {return base; } public inputStream getInputStream ()가 IoException {return uc.getInputStream (); } public int getContentLength ()가 IoException {return uc.getContentLength (); }};}코드에서 볼 수 있듯이 url.openConnection ()은 실제로 호출됩니다. 이렇게하면 완전한 체인을 연결할 수 있습니다.
UrlClassPath 클래스의 코드는 JDK에 자체적으로 제공되지 않습니다. 여기에서는 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/misc/urlclasspath.java#506을 참조하십시오
IDE/Open Directory에서 Spring Boot 응용 프로그램을 시작하십시오
위의 내용은 뚱뚱한 항아리에서 스프링 부트 응용 프로그램을 시작하는 과정에 대해서만 언급됩니다. 다음은 IDE에서 Spring Boot가 어떻게 시작되는지에 대한 분석입니다.
IDE에서 직접 실행되는 주요 기능은 자체 주요 기능을 적용하는 것입니다.
@SpringBootApplicationPublic Class SpringBootDemoApplication {public static void main (String [] args) {springApplication.run (springbootdemoApplication.class, args); }}실제로, Spring Boot 응용 프로그램을 IDE에서 시작하는 것이 가장 쉬운 경우입니다. 의존성 항아리가 클래스 경로에 들어가기 때문에 Spring Boot가 막 시작되었습니다.
또 다른 상황은 열린 디렉토리에서 Spring Boot를 시작하는 것입니다. 소위 오픈 디렉토리는 Fat Jar를 압축 한 다음 응용 프로그램을 직접 시작하는 것입니다.
java org.springframework.boot.loader.jarlauncher
현재 Spring Boot는 현재 디렉토리에 있는지 여부를 결정합니다. 그렇다면 폭발물을 구성하고 (이전의 것은 jarfilearchive), 후속 시작 프로세스는 Fat Jar와 유사합니다.
Tomcat 스타트 업 프로세스를 구축하십시오
웹 환경에 있는지 확인하십시오
Spring Boot가 시작되면 먼저 Servlet 클래스를 검색하여 웹 환경에 있는지 확인하십시오.
개인 정적 최종 문자열 [] web_environment_classes = { "javax.servlet.servlet", "org.springframework.web.context.configurablewebapplicationcontext"}; private boolean for (string classname : web_envernments). (! classutils.ispresent (classname, null)) {return false; }} return true;}그렇다면 AnnotationConfigemeddedWebApplicationContext가 생성됩니다. 그렇지 않으면 스프링 컨텍스트는 AnnotationConfigApplicationContext입니다.
//org.springframework.boot.springApplication Protected ConfigurableApplicationContext createEapplicationContext () {class <?> contextClass = this.ApplicationContextClass; if (contextClass == null) {try {contextclass = class.forname (this.webenvironment? default_web_context_class : default_context_class); } catch (classNotFoundException ex) {Throw New New ElegalStateException ( "불가능한 기본 ApplicationContext를 만들 수 없습니다." + "ApplicationContextClass를 지정하십시오", ex); }} return (configurableApplicationContext) beanutils.instantiate (contextClass); } EmbeddedServletContainerFactory의 구현 클래스를 얻으십시오
Spring Boot는 EmbeddedServletContainerFactory를 얻어 해당 웹 서버를 시작합니다.
일반적으로 사용되는 두 개의 구현 클래스는 tomcatembeddedservletcontainerfactory 및 jettyembeddedservletcontainerfactory입니다.
Tomcat을 시작하려는 코드 :
// tomcatembeddedservletcontainerfactory@atriadepublic embeddedservletcontainer getembeddedservletcontainer (servletcontextInitializer ... 이니셜 라이저) {tomcat tomcat = new tomcat (); file basedir = (this.basedirectory! = null? this.basedir : createTempdir ( "tomcat")); tomcat.setbasedir (basedir.getabsolutepath ()); 커넥터 커넥터 = 새 커넥터 (this.protocol); tomcat.getService (). addConnector (커넥터); CustomizeConnector (커넥터); tomcat.setconnector (커넥터); tomcat.gethost (). setAutodeploy (false); tomcat.getEngine (). SetbackgroundProcessOrdelay (-1); for (Connector additterConnector : this.additionalTomCatConnectors) {tomcat.getService (). addConnector (추가 콘월 어); } prepareContext (tomcat.gethost (), 이니셜 라이저); return getTomCatembeddedServletContainer (tomcat);} Tomcat에 대한 임시 파일 디렉토리는 다음과 같은 것입니다.
/tmp/tomcat.22233614112516545210.8080, Tomcat의 기초. 작업 디렉토리와 같은 임시 Tomcat 파일은 내부에 배치됩니다.
더 중요한 기본/JSP 서블릿과 같은 일부 Tomcat Servlet도 초기화됩니다.
private void addDefaultServlet (컨텍스트 컨텍스트) {랩퍼 defaultservlet = context.createWrapper (); defaultservlet.setName ( "default"); defaultservlet.setservletclass ( "org.apache.catalina.servlets.defaultservlet"); defaultservlet.addinitparameter ( "Debug", "0"); defaultservlet.addinitparameter ( "Listings", "False"); defaultservlet.setloadonstartup (1); // 그렇지 않으면 스프링 DispatcherServlet의 기본 위치를 defaultservlet.setoverRidable (true)을 설정할 수 없습니다. Context.addchild (defaultservlet); context.addservletmapping ( "/", "default");} private void addjspservlet (context context) {Wrapper jspservlet = context.createWrapper (); jspservlet.setName ( "jsp"); jspservlet.setservletclass (getjspservletclassName ()); jspservlet.addinitparameter ( "Fork", "False"); jspservlet.setloadonstartup (3); Context.addchild (jspservlet); context.addservletmapping ( "*. jsp", "jsp"); context.addservletmapping ( "*. jspx", "jsp");} Spring Boot 웹 애플리케이션으로 리소스에 액세스하는 방법
Spring Boot 응용 프로그램이 Fat Jar로 포장 될 때 웹 리소스에 어떻게 액세스합니까?
실제로 Archive가 제공 한 URL을 통해 구현 한 다음 ClassLoader에서 제공하는 ClassPath 리소스에 액세스 할 수있는 기능을 통해 구현됩니다.
index.html
예를 들어, 코드의 SRC/Main/Resources/STATIC 디렉토리에 직접 배치 할 수있는 Index.html을 구성해야합니다.
index.html 환영 페이지의 경우, 스프링 부트가 초기화되면 뷰 콘트롤러가 작성되도록 작성됩니다.
// ResourceProperTiesPublic Class ResourceProperties는 ResourcelOaderAware {private static final String [] servlet_resource_locations = { "/"}; 개인 정적 최종 문자열 [] classpath_resource_locations = { "classpath :/meta-inf/resources/", "classpath :/resources/", "classPath :/static/", "classPath :/public/"}; // webmvcautoconfigurationAdapter @override public void addViewControllers (viewControllerRegistry Registry) {resource page = this.resourceProperties.getWelcomePage (); if (page! = null) {logger.info ( "환영 페이지 추가 :" + page); registry.addViewController ( "/"). setViewName ( "proward : index.html"); }} 주형
예를 들어, 페이지 템플릿 파일은 SRC/Main/Resources/Template 디렉토리에 배치 할 수 있습니다. 그러나 이것은 실제로 템플릿 구현 클래스 자체에 의해 처리됩니다. 예를 들어, Thymeleafproperties 클래스에서 :
public static final String default_prefix = "classpath :/templates/";
JSP
JSP 페이지는 템플릿과 유사합니다. 실제로 스프링 MVC에 내장 된 JSTLVIEW를 통해 처리됩니다.
JSP 페이지의 디렉토리를 설정하려면 spring.view.prefix를 구성 할 수 있습니다.
spring.view.prefix :/web-inf/jsp/
스프링 부팅에서 통합 오류 페이지 처리
오류 페이지의 경우 BasicErrorController를 만들어 Spring Boot도 균일하게 처리됩니다.
@controller@requestmapping ( "$ {server.error.path : $ {error.path :/error}}") public class BasicErrorController는 AbsTracterrorController를 확장합니다해당보기는 간단한 HTML 알림입니다.
@configuration@conderfix = "server.error.whitelabel", name = "enabled", matchifmissing = true) @conditional (errortemplatemissingcondition.class) 보호 된 정적 클래스 화이트 라벨러가 최종 SpelView defaulterrorview = 새로운 spelview (new spelview) "<html> <hod> <h1> Whitelabel Error Page </h1>" + "<p>이 응용 프로그램은 명시적인 매핑/오류가 없으므로 폴백으로 표시됩니다. </p>" + "<div id = 'created'> $ {timestamp} </div>" + "<div> 예상되지 않은 오류가있었습니다 (type = $ {오류}, 상태 = $ {status}). @Bean (name = "error") @ConditionAlonMissingBean (name = "error") public view defaulterrorView () {return this.defaulterrorView; }Spring Boot는 우수한 관행으로, 기존 웹 응용 프로그램이 오류가 발생할 때 발생하는 기본 예외를 피하여 비밀을 쉽게 누출 할 수 있습니다.
Spring Boot 응용 프로그램의 Maven 포장 프로세스
먼저 Maven-Shade-Plugin을 통해 종속성이 포함 된 항아리를 생성 한 다음 Spring Boot Loader 및 Spring-Maven-Plugin 플러그인을 통해 Spring Boot Loader 및 Manifest.mf와 관련된 클래스를 포장하십시오.
스프링 부팅에서 컬러 로그 구현
쉘에서 스프링 부트 응용 프로그램을 시작할 때 로거 출력이 색상이되어 매우 흥미 롭습니다.
이 설정은 다음을 해제 할 수 있습니다.
spring.output.ansi.enabled = false
원칙은 AnsiOutPutApplicationListener를 통해이 구성을 얻은 다음 출력으로 로그백을 설정하고 ColorConverter를 추가 한 다음 org.springframework.ansi.ansioutput을 통해 일부 필드를 렌더링하는 것입니다.
일부 코드 팁
클래스 로더를 구현할 때 JDK7 병렬 로딩을 지원하십시오
LainkEdurlClassLoader에서 LockProvider를 참조 할 수 있습니다
Public Class LaunchEdUrlClassLoader 확장 URLCLASSLOADER {Private STATIC LOCKPROVIDER LOCK_PROVIDER = SETUPLOCKProvider (); Private Static LockProvider setUplockProvider () {try {classLoader.registerAsParalLelCapable (); 새로운 java7lockprovider ()를 반환합니다. } catch (nosuchmethoderror ex) {return new locprovider (); }} @override protected class <?> loadclass (문자열 이름, 부울 resolve)는 classNotFoundException {synchronized (unkendUrlClassLoader.lock_provider.getLock (this, name)) {class <?> loadedClass = findloadedClass (이름); if (loadedClass == null) {handler.setUseFastConnectionExceptions (true); try {loadedClass = doloadClass (이름); } 마침내 {handler.setUseFastConnectionExceptions (false); }} if (resolve) {resolveClass (loadedClass); } return loadedClass; }} JAR 패키지가 에이전트를 통해로드되었는지 확인
inputargumentsJavaagentDetector, 원리는 항아리의 URL에 "-javaagent :"의 접두사가 있는지 여부를 감지하는 것입니다.
개인 정적 최종 문자열 Java_agent_prefix = "-javaagent :";
프로세스의 PID를 얻으십시오
ApplicationPid, PID를 얻을 수 있습니다.
개인 문자열 getPid () {try {String jvmname = manageFactory.getRuntImemxBean (). getName (); reture jvmname.split ( "@") [0]; } catch (Throwable ex) {return null; }} 포장 로거 클래스
Spring Boot에는 Java, Log4J, Log4J2, Logback을 지원하는 로거 세트가 있습니다. 앞으로 로거를 포장해야 할 때이를 참조 할 수 있습니다.
org.springframework.boot.logging 패키지 아래
원본 시작 메인 기능을 얻으십시오
스택에서 얻은 방법을 통해 주요 함수를 판단하고 원본 시작 메인 기능을 찾으십시오.
private class <?> complucemainApplicationClass () {try {stackTraceElement [] stackTrace = new runtimeexception (). getStackTrace (); for (stackTraceElement stackTraceElement : stackTrace) {if ( "main".Equals (stackTraceElement.getMethodName ())) {return class.forname (stackTraceElement.getClassName ()); }}} catch (classNotFoundException ex) {// 삼키고 계속} return null;} Spirng 부츠의 일부 단점 :
스프링 부트 응용 프로그램이 뚱뚱한 병에서 실행되면 일부 문제가 발생합니다. 내 개인적인 의견은 다음과 같습니다.
요약
Spring Boot는 JAR 프로토콜을 확장하고, 아카이브 개념을 추상화하고, 지원하는 Jarfile, JarurlConnection 및 LaunchedUrlClassLoader를 추출하여 상단 계층 응용 프로그램에 대한 인식없이 하나의 개발 경험을 실현합니다. 실행 가능한 전쟁은 봄이 제안한 개념이 아니지만 Spring Boot는이를 수행 할 수있게합니다.
Spring Boot는 놀라운 프로젝트로, 봄의 두 번째 봄이라고 할 수 있습니다. Spring-Cloud-Config, Spring Session, Metrics, Remote Shell 등은 개발자가 좋아하는 모든 프로젝트 및 기능입니다. 디자이너가 최전선 개발에 대한 풍부한 경험을 가지고 있으며 개발자의 고통을 잘 알고 있습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.