Kommentaren til @ServletComponentScan i Spring Boot

1. Oversikt

I denne artikkelen vil vi gå gjennom det nye @ServletComponentScan kommentar i Vårstøvel.

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

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

@WebServlet, @WebFilter, og @WebListener merkede klasser kan automatisk registreres med en innebygd Servlet container ved å kommentere @ServletComponentScan på en @Konfigurasjon klasse og spesifisere pakkene.

Vi har introdusert den grunnleggende bruken av @WebServlet i Introduksjon til Java Servlets og @WebFilter i Introduksjon til avskjæring av filtermønster i Java. Til @WebListener, kan du ta en titt på denne artikkelen som viser et typisk brukstilfelle for nettlyttere.

2. Servlets, Filtre, og Lyttere

Før du dykker inn i @ServletComponentScanla oss ta en titt på hvordan kommentarene: @WebServlet, @WebFilter og @WebListener ble brukt før @ServletComponentScan kom til spill.

2.1. @WebServlet

Nå skal vi først definere en Servlet som serverer forespørsler og svarer "Hallo":

@WebServlet ("/ hallo") offentlig klasse HelloServlet utvider HttpServlet {@Override public void doGet (HttpServletRequest request, HttpServletResponse response) {try {response .getOutputStream () .write ("hallo"); } fange (IOException e) {e.printStackTrace (); }}}

2.2. @WebFilter

Deretter et filter som filtrerer forespørsler om å målrette "/Hallo"og prepends “Filtrering“ til utgangen:

@WebFilter ("/ hallo") 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

Til slutt, en lytter som setter et tilpasset attributt inn 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 Container

Nå som vi har bygget de grunnleggende komponentene i en enkel webapplikasjon, kan vi pakke og distribuere den til en Servlet container. Hver komponents oppførsel kan lett verifiseres ved å distribuere den pakkede krigsfilen i Brygge, Tomcat eller noen Servlet containere som støtter Servlet 3.0.

3. Bruke @ServletComponentScan i Vårstøvel

Du lurer kanskje på siden vi kan bruke disse kommentarene i de fleste Servlet containere uten konfigurasjon, hvorfor trenger vi @ServletComponentScan? Problemet ligger i innebygd Servlet containere.

På grunn av det faktum at innebygde containere ikke støtter @WebServlet, @WebFilter og @WebListener merknader, Vårstøvel, stole sterkt på innebygde containere, introduserte denne nye kommentaren @ServletComponentScan for å støtte noen avhengige krukker som bruker disse 3 kommentarene.

Den detaljerte diskusjonen finner du i denne utgaven på Github.

3.1. Maven avhengigheter

Å bruke @ServletComponentScan, vi trenger Vårstøvel med versjon 1.3.0 eller nyere. La oss legge til den siste versjonen av 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 hjelp av @ServletComponentScan

De Vårstøvel appen er ganske enkel. Vi legger til @ServletComponentScan for å aktivere skanning etter @WebFilter, @WebListener og @WebServlet:

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

Uten noen endring i forrige webapplikasjon, fungerer det bare:

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

3.3. Spesifiser pakker som skal skannes

Som standard, @ServletComponentScan vil skanne fra pakken til den merkede klassen. For å spesifisere hvilke pakker som skal skannes, kan vi bruke attributtene:

  • verdi
  • basePackages
  • basePackageClasses

Standaren verdi attributt er et alias for basePackages.

Si vår SpringBootAnnotatedApp er under pakke com.baeldung.annotation, og vi vil skanne klasser i pakken com.baeldung.annotation.components opprettet i webapplikasjonen ovenfor, er følgende konfigurasjoner ekvivalente:

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

4. Under hetten

De @ServletComponentScan merknader behandles av ServletComponentRegisteringPostProcessor. Etter skanning av spesifiserte pakker for @WebFilter, @WebListener og @WebServlet merknader, en liste over ServletComponentHandlers vil behandle merkeattributtene og registrere skannede bønner:

klasse ServletComponentRegisteringPostProcessor implementerer BeanFactoryPostProcessor, ApplicationContextAware {private static final List HANDLERS; statisk {List handlers = new 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 offisielle Javadoc, @ServletComponentScan kommentar fungerer bare i innebygd Servlet containere, som er det som følger med Vårstøvel som standard.

5. Konklusjon

I denne artikkelen introduserte vi @ServletComponentScan og hvordan den kan brukes til å støtte applikasjoner som er avhengige av kommentarene: @WebServlet, @WebFilter, @WebListener.

Implementeringen av eksemplene og koden finner du i GitHub-prosjektet.


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