복붙노트

[SPRING] 봄 시작 성능 문제

SPRING

봄 시작 성능 문제

저는 수천 개의 클래스가있는 꽤 큰 응용 프로그램에서 Spring을 통합하려고합니다. 구성 요소 검색 때문에 컨테이너를 시작하는 데 많은 시간이 걸립니다.

나는 "기본 패키지"에 지정된 디렉토리의 수를 무관 한 디렉토리를 검색하는 데 낭비되는 시간을 줄이기 위해 최소로 좁혔지만 초기화의 클래스 경로 스캐닝 부분은 여전히 ​​약 1-2 분이 걸린다.

그렇다면 스캐닝 프로세스를 최적화 할 수있는 방법이 있습니까? 후보 클래스 경로를 파일에 저장하고 컨테이너를 만들어서 시작할 때마다 클래스 경로를 검사하는 대신 파일에서 가져 오는 방법을 생각했지만 실제로 시작해야하는지 또는 가능한지 알지 못합니다. .

어떤 조언을 많이 주시면 감사하겠습니다. 미리 감사드립니다.

편집 : 자동 생성 된 XML 파일에서 bean 정의를로드하면 스프링 부트 스트랩 시간이 9-10 초로 단축되어 Spring이 컴포넌트 클래스 경로 검색에 사용하는 리플렉션 API가 시작 지연의 주요 소스임을 확인합니다. 같은 문제가있는 사람에게 도움이 될 수 있기 때문에 xml 파일을 생성하는 방법은 코드입니다.

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;


public class ConfigurationWriter {

    public ArrayList<String> beanDefinitions = new ArrayList<String>();

    public ConfigurationWriter() {

        // the context loaded with old fashioned way (classpath scanning)
        ApplicationContext context = SpringContainerServiceImpl.getInstance().getContext();
        String[] tab = context.getBeanDefinitionNames();
        for (int i = 0; i < tab.length - 6; i++) {
            Class clazz = context.getType(tab[i]);
            String scope = context.isPrototype(tab[i]) ? "prototype" : "singleton";
            String s = "<bean id=\"" + tab[i] + "\" class=\"" + clazz.getName() + "\" scope=\"" + scope + "\"/>";
            beanDefinitions.add(s);
        }
        // Collections.addAll(beanDefinitions, tab);

    }

    @SuppressWarnings("restriction")
    public void generateConfiguration() throws FileNotFoundException {
        File xmlConfig = new File("D:\\dev\\svn\\...\\...\\src\\test\\resources\\springBoost.xml");
        PrintWriter printer = new PrintWriter(xmlConfig);

        generateHeader(printer);

        generateCorpse(printer);

        generateTail(printer);

        printer.checkError();

    }

    @SuppressWarnings("restriction")
    private void generateCorpse(PrintWriter printer) {

        for (String beanPath : beanDefinitions) {
            printer.println(beanPath);
        }

    }

    @SuppressWarnings("restriction")
    private void generateHeader(PrintWriter printer) {
        printer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        printer.println("<beans xmlns=\"http://www.springframework.org/schema/beans\"");
        printer.println("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
        printer.println("xmlns:context=\"http://www.springframework.org/schema/context\"");
        printer.println("xsi:schemaLocation=\"");
        printer.println("http://www.springframework.org/schema/mvc");
        printer.println("http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd");
        printer.println("http://www.springframework.org/schema/beans");
        printer.println("http://www.springframework.org/schema/beans/spring-beans-3.0.xsd");
        printer.println("http://www.springframework.org/schema/context");
        printer.println("http://www.springframework.org/schema/context/spring-context-3.0.xsd\"");
        printer.println("default-lazy-init=\"true\">");
    }

    @SuppressWarnings("restriction")
    private void generateTail(PrintWriter printer) {
        // printer.println("<bean class=\"com.xxx.frmwrk.spring.processors.xxxBeanFactoryPostProcessor\"/>");
        printer.println("<bean class=\"com.xxx.frmwrk.spring.processors.xxxPostProcessor\"/>");
        printer.println("</beans>");
    }

}

해결법

  1. ==============================

    1.문제가 실제로 컴포넌트 스캔과 bean 초기화 프로세스가 아니라면 (그리고 나는 그것을 의심 스럽다.) 컴포넌트 스캔 대신 Spring XML 설정을 사용하는 것이 유일한 해결책이다. - (자동으로 XML 파일을 만들 수 있습니다.)

    문제가 실제로 컴포넌트 스캔과 bean 초기화 프로세스가 아니라면 (그리고 나는 그것을 의심 스럽다.) 컴포넌트 스캔 대신 Spring XML 설정을 사용하는 것이 유일한 해결책이다. - (자동으로 XML 파일을 만들 수 있습니다.)

    하지만 수업 수가 많고 그 중 90 % ~ 100 %가 Beans라면 스캔 한 파일의 축소는 10 % -0 %의 최대 향상을 보입니다.

    초기화 속도를 높이기 위해 다른 방법을 시도하거나, 지연로드 또는 지연로드 관련 기술을 사용하거나, 조크가 아닌 빠른 하드웨어를 사용해야합니다 (독립 실행 형 응용 프로그램이 아닌 경우).

    Spring XML을 생성하는 쉬운 방법은 원래 애플리케이션과 같은 클래스 경로 스캐닝을 사용하는 간단한 스프링 애플리케이션을 작성하는 것이다. 모든 Bean이 초기화 된 후에는 Spring Context에서 Bean을 반복하여 Bean이 중요한 패키지에 속하는지 확인하고이 Bean에 대한 XML Config를 파일에 작성한다.

  2. ==============================

    2.주석 첨부 클래스의 자동 검출은, 현재, 지정된 패키지 내의 모든 클래스를 스캔 할 필요가있어, 현재의 클래스로드기구의 문제라고하는 장시간이 걸릴 가능성이 있습니다.

    주석 첨부 클래스의 자동 검출은, 현재, 지정된 패키지 내의 모든 클래스를 스캔 할 필요가있어, 현재의 클래스로드기구의 문제라고하는 장시간이 걸릴 가능성이 있습니다.

    Java 9는 Jigsaw에서 여기서 도움이 될 것입니다.

    Java Platform Module에서 Mark Reinold의 시스템 요구 사항, http://openjdk.java.net/projects/jigsaw/spec/reqs/ :

    효율적인 주석 검출 - 특정 주석이 실제로 모든 클래스 파일을 읽지 않고 존재하는 모듈 아티팩트의 모든 클래스 파일을 식별 할 수 있어야합니다. 실행시 런타임에 주석이 유지되는 한 모듈의 모든 클래스를 열거하지 않고 특정 주석이있는로드 된 모듈의 모든 클래스를 식별 할 수 있어야합니다. 효율성을 위해 특정 주석 만이 방식으로 탐지 할 수 있도록 지정해야 할 수도 있습니다. 한 가지 가능한 접근법은 각 주석이 적용되는 요소의 표시와 함께 모듈에있는 주석의 색인을 사용하여 모듈 정의를 보강하는 것입니다. 인덱스의 크기를 제한하기 위해 @Indexed와 같은 새로운 메타 주석으로 주석이 달린 주석 만 포함됩니다.

  3. ==============================

    3.성능에 대해서는별로 할 수 없지만 프로덕션 환경에서의 시작과 관련이 없지만 테스트 시작 시간은 중요합니다. 두 가지 팁 :

    성능에 대해서는별로 할 수 없지만 프로덕션 환경에서의 시작과 관련이 없지만 테스트 시작 시간은 중요합니다. 두 가지 팁 :

  4. ==============================

    4.스캔 할 디렉토리를 줄이는 것 이외에는 게으른 bean 초기화를 사용하는 것뿐입니다. 콩이 많이 있으면 도움이 될 수 있습니다.

    스캔 할 디렉토리를 줄이는 것 이외에는 게으른 bean 초기화를 사용하는 것뿐입니다. 콩이 많이 있으면 도움이 될 수 있습니다.

  5. ==============================

    5.구성 요소 검사 대신 Spring의 Java 기반 컨테이너 구성을 사용할 수 있습니다.

    구성 요소 검사 대신 Spring의 Java 기반 컨테이너 구성을 사용할 수 있습니다.

    XML 기반 구성과 비교하여 Java 기반 컨테이너 구성은 유형에 안전합니다.

    하지만 먼저 구성 요소 스캔 경로가 타사 라이브러리의 클래스를 포함하지 않도록 충분히 구체적인지 여부를 확인해야합니다.

  6. ==============================

    6.나는 그것이 오래된 질문이며, 그 당시 상황이 다르다는 것을 알 수 있듯이, 그러나 내가 바라는대로이 문제를 연구하는 다른 사람들을 도울 수 있기를 바랍니다.

    나는 그것이 오래된 질문이며, 그 당시 상황이 다르다는 것을 알 수 있듯이, 그러나 내가 바라는대로이 문제를 연구하는 다른 사람들을 도울 수 있기를 바랍니다.

    이 다른 질문에 대한 대답에 따르면, @ComponentScan 주석은 이제 시작 시간을 줄이는 데 도움이되는 lazyInit 플래그를 지원합니다.

    https://stackoverflow.com/a/29832836/4266381

    참고 : XML로 전환하는 것만 큼 편집이 마술처럼 바뀌 었습니다. 그러나 코드를 자세히 살펴보면 default-lazy-init = "true"가됩니다. 그게 진정한 이유 였는지 궁금합니다.

  7. from https://stackoverflow.com/questions/5947713/spring-startup-performance-issues by cc-by-sa and MIT license