Kommentar til @ ServletComponentScan i Spring Boot

1. Oversigt

I denne artikel gennemgår vi det nye @ServletComponentScan kommentar i Spring Boot.

Målet er at støtte følgende Servlet 3.0 kommentarer:

  • javax.servlet.annotation.WebFilter
  • javax.servlet.annotation.WebListener
  • javax.servlet.annotation.WebServlet

@WebServlet, @WebFilterog @WebListener annoterede klasser kan automatisk registreres med en integreret Servlet container ved at kommentere @ServletComponentScan på en @Konfiguration klasse og specificering af pakkerne.

Vi har introduceret den grundlæggende brug af @WebServlet i Introduktion til Java Servlets og @WebFilter i introduktion til aflytning af filtermønster i Java. Til @WebListener, kan du kigge på denne artikel, der viser et typisk brugstilfælde for weblyttere.

2. Servlets, Filtreog Lyttere

Før du dykker ned i @ServletComponentScan, lad os se på hvordan kommentarerne: @WebServlet, @WebFilter og @WebListener blev brugt før @ServletComponentScan kom i spil.

2.1. @WebServlet

Nu definerer vi først en Servlet der tjener anmodninger og svar "Hej":

@WebServlet ("/ hej") offentlig klasse HelloServlet udvider HttpServlet {@Override public void doGet (HttpServletRequest anmodning, HttpServletResponse svar) {prøv {respons .getOutputStream () .write ("hej"); } fange (IOException e) {e.printStackTrace (); }}}

2.2. @WebFilter

Derefter et filter, der filtrerer anmodninger om at målrette mod "/Hej"og forbereder “Filtrering“ til output:

@WebFilter ("/ hej") offentlig klasse HelloFilter implementerer filter {// ... @ Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) kaster IOException, ServletException {servletResponse .getOutputStream ("print"). ); filterChain.doFilter (servletRequest, servletResponse); } // ...}

2.3. @WebListener

Endelig en lytter, der indstiller en brugerdefineret attribut i ServletContext:

@WebListener offentlig klasse AttrListener implementerer ServletContextListener {@Override public void contextInitialized (ServletContextEvent servletContextEvent) {servletContextEvent .getServletContext () .setAttribute ("servlet-context-attr", "test"); } // ...}

2.4. Implementere til en Servlet Beholder

Nu hvor vi har bygget de grundlæggende komponenter i en simpel webapplikation, kan vi pakke og implementere den i en Servlet beholder. Hver komponents adfærd kan let verificeres ved at indsætte den pakkede krigsfil i Anløbsbro, Tomcat eller nogen Servlet containere, der understøtter Servlet 3.0.

3. Brug @ServletComponentScan i Spring Boot

Du undrer dig måske, da vi kan bruge disse kommentarer i de fleste Servlet containere uden nogen konfiguration, hvorfor har vi brug for det @ServletComponentScan? Problemet ligger i indlejret Servlet containere.

På grund af det faktum, at indlejrede containere ikke understøtter @WebServlet, @WebFilter og @WebListener anmærkninger, Spring Boot, stole meget på indlejrede containere, introducerede denne nye kommentar @ServletComponentScan til at understøtte nogle afhængige krukker, der bruger disse 3 kommentarer.

Den detaljerede diskussion kan findes i dette nummer på Github.

3.1. Maven afhængigheder

At bruge @ServletComponentScan, vi behøver Spring Boot med version 1.3.0 eller nyere. Lad os tilføje den nyeste version af spring-boot-starter-parent og spring-boot-starter-web til pom:

 org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE 
  org.springframework.boot spring-boot-starter-web 1.5.1.RELEASE 

3.2. Ved brug af @ServletComponentScan

Det Spring Boot app er ret enkel. Vi tilføjer @ServletComponentScan for at aktivere scanning efter @WebFilter, @WebListener og @WebServlet:

@ServletComponentScan @ SpringBootApplication offentlig klasse SpringBootAnnotatedApp {public static void main (String [] args) {SpringApplication.run (SpringBootAnnotatedApp.class, args); }}

Uden nogen ændring af den forrige webapplikation fungerer det bare:

@Autowired privat TestRestTemplate restTemplate; @Test offentlig ugyldighed givenServletFilter_whenGetHello_thenRequestFiltered () {ResponseEntity responsEntity = restTemplate.getForEntity ("/ hej", String.class); assertEquals (HttpStatus.OK, responseEntity.getStatusCode ()); assertEquals ("filtrering hej", responseEntity.getBody ()); }
@Autowired privat ServletContext servletContext; @Test offentlig ugyldighed givenServletContext_whenAccessAttrs_thenFoundAttrsPutInServletListner () {assertNotNull (servletContext); assertNotNull (servletContext.getAttribute ("servlet-context-attr")); assertEquals ("test", servletContext.getAttribute ("servlet-context-attr")); }

3.3. Angiv pakker, der skal scannes

Som standard, @ServletComponentScan scanner fra pakken i den kommenterede klasse. For at specificere hvilke pakker der skal scannes, kan vi bruge dets attributter:

  • værdi
  • basePackages
  • basePackageClasses

Standardindstillingen værdi attribut er et alias for basePackages.

Sig vores SpringBootAnnotatedApp er under pakke com.baeldung.annotation, og vi vil scanne klasser i pakke com.baeldung.annotation.components oprettet i webapplikationen ovenfor, er følgende konfigurationer ækvivalente:

@ServletComponentScan
@ServletComponentScan ("com.baeldung.annotation.components")
@ServletComponentScan (basePackages = "com.baeldung.annotation.components")
@ServletComponentScan (basePackageClasses = {AttrListener.class, HelloFilter.class, HelloServlet.class})

4. Under hætten

Det @ServletComponentScan annotering behandles af ServletComponentRegistringPostProcessor. Efter scanning af specificerede pakker til @WebFilter, @WebListener og @WebServlet kommentarer, en liste over ServletComponentHandlers behandler deres annoteringsattributter og registrerer scannede bønner:

klasse ServletComponentRegisteringPostProcessor implementerer BeanFactoryPostProcessor, ApplicationContextAware {privat statisk endelig Liste HÅNDTAGERE; statisk {List handlers = ny ArrayList (); handlers.add (ny WebServletHandler ()); handlers.add (ny WebFilterHandler ()); handlers.add (ny WebListenerHandler ()); HANDLERS = Collections.unmodifiableList (handlers); } // ... private void scanPackage (ClassPathScanningCandidateComponentProvider componentProvider, String packageToScan) {// ... for (ServletComponentHandler handler: HANDLERS) {handler.handle ((((ScannedGenericBeanDefinition) kandidat), (BeanDefinitionRegistry) this.application; }}}

Som sagt i den officielle Javadoc, @ServletComponentScan kommentar fungerer kun i integreret Servlet containere, hvilket er hvad der følger med Spring Boot som standard.

5. Konklusion

I denne artikel introducerede vi @ServletComponentScan og hvordan det kan bruges til at understøtte applikationer, der afhænger af en af ​​kommentarerne: @WebServlet, @WebFilter, @WebListener.

Implementeringen af ​​eksemplerne og koden findes i GitHub-projektet.


$config[zx-auto] not found$config[zx-overlay] not found