Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-9795

Can't component scan for @Component and exclude @Controller (a.k.a., excludeFilters should take precedence over includeFilters)

    XMLWordPrintable

    Details

    • Last commented by a User:
      true

      Description

      Like many, I wanted my services, repositories and the like managed by the application context and my controllers by the framework servlet. So, for my application context configuration class I used the following annotation:

      @ComponentScan(basePackageClasses={
              com.package.Marker.class
      }, useDefaultFilters=true, includeFilters={
              @ComponentScan.Filter(Aspect.class)
      }, excludeFilters={
              @ComponentScan.Filter(Controller.class)
      })

      And for my framework servlet configuration I used:

      @ComponentScan(basePackageClasses={
              com.package.Marker.class
      }, useDefaultFilters=false, includeFilters={
              @ComponentScan.Filter(Controller.class)
      })

      However, my controllers were getting instantiated twice: once in the application context and once in the framework servlet. So I tried the following iterations of my application context config class annotation:

      @ComponentScan(basePackageClasses={
              com.package.Marker.class
      }, useDefaultFilters=false, includeFilters={
              @ComponentScan.Filter(Aspect.class), @ComponentScan.Filter(Component.class),
              @ComponentScan.Filter(Repository.class), @ComponentScan.Filter(Service.class)
      })
      @ComponentScan(basePackageClasses={
              com.package.Marker.class
      }, useDefaultFilters=false, includeFilters={
              @ComponentScan.Filter(Aspect.class), @ComponentScan.Filter(Component.class),
              @ComponentScan.Filter(Repository.class), @ComponentScan.Filter(Service.class)
      }, excludeFilters={
              @ComponentScan.Filter(Controller.class)
      })

      Neither of those worked. Controllers were instantiated twice. I figured this is because the @Controller annotation is itself annotated with @Component. So, with that, THIS worked:

      @ComponentScan(basePackageClasses={
              com.package.Marker.class
      }, useDefaultFilters=false, includeFilters={
              @ComponentScan.Filter(Aspect.class), @ComponentScan.Filter(Repository.class),
              @ComponentScan.Filter(Service.class)
      })

      However, that doesn't achieve what I want, because I want classes marked @Component to be instantiated, I just don't want classes marked @Controller to be instantiated.

      In short, it seems to me that if I explicitly say "exclude classes matching these filters from component scanning," that should take precedence over all else. Especially important: if I say "use default filters" and then provide exclusions, those exclusions should NOT be ignored.

      I do not know whether this same problem exists with XML configuration. Presumable it does, but I'm not in a position to test that at the moment.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              pwebb Phil Webb
              Reporter:
              guitarking117 Nick Williams
              Last updater:
              Spring Issues Spring Issues
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Days since last comment:
                3 years, 24 weeks, 5 days ago