Servlet3.0 - 모듈식 및 동적 서브렛

6941 단어
오늘 Tomcat 소스를 보면서 SCI라는 단어를 발견했어요. 궁금ing...그냥 가봤어요. servlet 3.0의 새로운 특성.먼저 내가 어디에서 그를 발견했는지 살펴보자. 대략ContextConfig의 웹Config()에서 이 함수의 작용에 대해 서브렛의 작업 원리를 살펴보자.
  • Anything and everything can override the global and host defaults. * This is implemented in two parts * - Handle as a webfragment that gets added after everything else takes priority * - Mark Servlets as overridable so SCI configuration can replace * configuration from the defaults 대략적인 의미로 글로벌 및 host level의 기본 웹을 말합니다.xml은 모든 것에 덮어쓸 수 있습니다. 주요 실현 방식은 두 부분입니다. 하나는 @HandlesTypes 주석을 사용하여 servlet을 웹fragment으로 설명하고, 다른 하나는 SCI입니다.

  • 여기까지만 설명하고 서브렛 3.0의 새로운 기능들이 있는데,
  • @WebServlet, WebFilter, WebListner 세 개의 주석을 사용하여 웹을 대체합니다.xml 파일의 서브렛, Filter, Listner 구성;서브렛 3.0의 배포 설명 파일 웹.xml의 맨 윗부분 탭에metadata-complete 속성이 있습니다. 이 속성은 현재 배치 설명 파일이 완전한지 여부를 지정합니다.true로 설정하면 용기는 배치할 때 배치 설명 파일에만 의존하고 모든 주석을 무시합니다. (웹-fragment.xml 스캔을 건너뛰거나 플러그인 지원을 사용하지 않습니다. 이 속성을 설정하지 않거나false로 설정하지 않으면 플러그인 지원을 사용합니다.
  • 웹 서브렛 3.0 모듈화는 원래 웹 응용 프로그램의 모든 설정이 웹에 필요합니다.xml에서 진행하기 때문에 웹을 사용할 수 있습니다.xml이 혼란스러워지고 유연성이 떨어지기 때문에 서브렛 3.0은 모든 서브렛, Filter, Listener를jar 패키지로 만들어WEB-INF\lib에 넣을 수 있다.각각의 모듈에 각각의 프로필이 있으니 주의하십시오. 이 프로필의 이름은 웹-fragment입니다.xml ;(주의: 설정 파일의 이름은 이것이어야 합니다)
  • 방법을 사용하여 서브렛을 작성하고jar 패키지를 컴파일하여 이jar 패키지의 META-INF의 manfest를 삭제하고 웹-fragment를 추가합니다.xml;


  • 한 웹 응용 프로그램에 여러 개의 웹-fragment가 나타날 수 있기 때문이다.xml 성명 파일, 웹을 추가합니다.xml 파일, 불러오는 순서 문제가 어쩔 수 없는 문제가 되었습니다.web-fragment.xml은 선택할 수 있는 두 개의 맨 윗부분 라벨을 포함하고 있으며, 현재 파일에 명확한 불러오는 순서를 지정하려면 보통 이 두 개의 라벨을 사용해야 한다. 주로 현재 파일을 표시하는 데 사용되고, 선후 순서를 지정하는 데 사용된다.간단한 예는 다음과 같습니다.
    
        FragmentA
        
            
                FragmentB
                FragmentC
            
        
            
        
        
    
    
    

    위에서 보듯이, 탭의 값은 보통 다른 웹-fragment에 의해 추출됩니다.xml 파일은 선후 순서를 정의할 때 인용되며 현재 파일에서는 일반적으로 사용되지 않으며 현재 파일을 표시하는 역할을 한다.위의 특성을 알고 나면 지금 우리는
  • 웹 응용 프로그램에 서브렛(Listener, Filter) 구성을 추가하는 세 가지 방법이 있습니다.
  • 웹을 사용합니다.xml
  • 웹-fragment를 사용합니다.xml
  • 메모 사용
  • 동적 배포 서브렛, 필터, 모니터, 서브렛과 필터에 URL 매핑을 추가하는 등 서브렛Context는 동적 서브렛을 구성하는 다음과 같은 방법을 추가했습니다
  • .
    ServletRegistration.Dynamic addServlet(String servletName,Class extends Servlet> servletClass)
    ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
    ServletRegistration.Dynamic addServlet(String servletName, String className)
         T createServlet(Class clazz)
    ServletRegistration getServletRegistration(String servletName)
    Map getServletRegistrations()
    

    그 중에서 앞의 세 가지 방법의 작용은 같지만 매개 변수의 유형이 다를 뿐이다.createServlet () 방법으로 만든 서브렛은 일반적으로 사용자 정의 설정을 한 다음addServlet () 방법으로 서비스에 사용할 수 있는 서브렛으로 동적 등록합니다.두 개의 getServlet Registration () 방법은 주로 동적으로 서브렛에 맵 정보를 추가하는 데 사용되며, 이것은 웹과 같다.xml (또는 웹-fragment.xml) 에서 존재하는 서브렛에 맵 정보를 추가하기 위해 탭을 사용합니다.
    위와 같은 서브렛 Context에서 추가된 방법은 서브렛 Context Listener의 contexInitialized 방법에서 호출되거나 서브렛 ContainerInitializer의onStartup () 방법에서 호출됩니다.(구체적 실현에 의해 결정됨) 서브렛 컨테이너 Initializer는 서브렛 3.0에 추가된 인터페이스(즉 시작된SCI)로 용기가 시작할 때 SPI를 사용하여 서브렛 컨테이너 Initializer의 실현을 발견한다.다음은 내가 예시 코드를 제시한다
  • 서브렛ContextListener 기반
  •     public void contextInitialized(ServletContextEvent sce) {
    
            ServletContext sc = sce.getServletContext();
    
            // Register Servlet
            ServletRegistration sr = sc.addServlet("DynamicServlet",
                "web.servlet.dynamicregistration_war.TestServlet");
            sr.setInitParameter("servletInitName", "servletInitValue");
            sr.addMapping("/*");
    
            // Register Filter
            FilterRegistration fr = sc.addFilter("DynamicFilter",
                "web.servlet.dynamicregistration_war.TestFilter");
            fr.setInitParameter("filterInitName", "filterInitValue");
            fr.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST),
                                         true, "DynamicServlet");
    
            // Register ServletRequestListener
            sc.addListener("web.servlet.dynamicregistration_war.TestServletRequestListener");
        }
    
  • ServletContainerInitializer 기반으로jar에META-INF/services/javax를 포함해야 합니다.servlet.ServletContainerInitializer 파일, 파일 내용은 ServletContainerInitializer 인터페이스가 이미 구현된 클래스입니다. 예를 들어springWeb의 구현 org입니다.springframework.web.SpringServletContainerInitialzer
  • @HandlesTypes(WebApplicationInitializer.class)
    public class SpringServletContainerInitializer implements ServletContainerInitializer {
    
        @Override
        public void onStartup(@Nullable Set> webAppInitializerClasses, ServletContext servletContext)
                throws ServletException {
    
            List initializers = new LinkedList<>();
    
            if (webAppInitializerClasses != null) {
                for (Class> waiClass : webAppInitializerClasses) {
                    // Be defensive: Some servlet containers provide us with invalid classes,
                    // no matter what @HandlesTypes says...
                    if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
                            WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                        try {
                            initializers.add((WebApplicationInitializer)
                                    ReflectionUtils.accessibleConstructor(waiClass).newInstance());
                        }
                        catch (Throwable ex) {
                            throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
                        }
                    }
                }
            }
    
            if (initializers.isEmpty()) {
                servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
                return;
            }
    
            servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
            AnnotationAwareOrderComparator.sort(initializers);
            for (WebApplicationInitializer initializer : initializers) {
                initializer.onStartup(servletContext);
            }
        }
    
    }
    
    

    @HandlesTypes 주석은 SpringServlet Container Initializer가 처리하는 클래스를 나타냅니다. 표시된 클래스는onStartup 방법으로 매개 변수 값으로 전송되어야 합니다. onStartup 방법에서는set>c를 통해 얻을 수 있습니다.ContextConfig 감청기는 용기가 시작될 때 모든 웹 응용 프로그램의 WEB-INF/lib 디렉터리에 포함된jar 패키지의 META-INF/services/javax를 읽습니다.servlet.Servlet Container Initializer 및 웹 루트 디렉토리에 있는 META-INF/services/javax.servlet.Servlet Container Initializer, 반사를 통해 이 Servlet Container Initializer의 실례화를 완성한 다음에 Context 용기에 설정하면 마지막에 Context 용기가 시작될 때 각각 Servlet Container Initializer의 onStartup 방법을 호출합니다

    좋은 웹페이지 즐겨찾기