New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't component scan for @Component and exclude @Controller (a.k.a., excludeFilters should take precedence over includeFilters) [SPR-9795] #14428
Comments
Chris Beams commented Thanks Nick, will take a look at this. In the meantime, feel free to submit a simple reproduction project. |
Nick Williams commented By the way, since I reported this I have confirmed that this problem does not exist in the XML equivalent of the configuration above (forgive any misspellings, these were transcribed, not copied and pasted): <context:component-scan base-package="com.package" use-default-filters="true">
<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context> <context:component-scan base-package="com.package" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context> So, the above works just as expected. The application context instantiates This should work the same as my applicationContext.xml above (it does not): @ComponentScan(basePackageClasses={
com.package.Marker.class
}, useDefaultFilters=true, includeFilters={
@ComponentScan.Filter(Aspect.class)
}, excludeFilters={
@ComponentScan.Filter(Controller.class)
}) And this should work the same as my servletContext.xml above (it does): @ComponentScan(basePackageClasses={
com.package.Marker.class
}, useDefaultFilters=false, includeFilters={
@ComponentScan.Filter(Controller.class)
}) |
Phil Webb commented Hi Nick, After a bit of digging I think this might not actually be a bug. From your notes it looks like your two Try adding an additional exclude filter to prevent the second configuration class from being found. If you don't want any Application: @ComponentScan(
basePackageClasses={com.package.Marker.class},
useDefaultFilters=true,
includeFilters={@Filter(Aspect.class)},
excludeFilters={@Filter(Controller.class, Configuration.class)}) Servlet: @ComponentScan(
basePackageClasses={com.package.Marker.class},
useDefaultFilters=false,
includeFilters={@Filter(Controller.class)
}) I have created a repro project to show the fix: Cheers, |
Nick Williams commented Phil, this is not correct. Here is my actual project structure for the concerned classes:
The actual basePackageClasses value is com.companyname.product.health.Marker.class. This is not in the same package as the config classes. Therefore, this is not the cause of the issue. |
Nick Williams commented (Sorry that the comment was improperly formatted before. I have resolved this.) |
Phil Webb commented Hi Nick, Thanks for the update, I thought I was onto the root cause there! I am having some trouble replicating the issue, could you take a look at #14428 in https://github.com/SpringSource/spring-framework-issues to see if you can see any obvious differences between that project and your code. Cheers, |
Nick Williams commented OMG ... I'm so sorry I wasted your time, Phil (and my time). I just spent the last two hours slowly building a reproduction project and bit by bit I couldn't get it to reproduce, up until the point that I had replicated the entire project and still couldn't get it to reproduce. I couldn't figure out what the @$#! was going on, and then I realized... The Marker.java was in the wrong package. ... I can't tell you how many months I have looked at that folder structure and never realized it was in the wrong package. I KNEW it was supposed to be in .product, I KNEW putting it above .product (and, thus, above .config) could cause problems, and I KNEW that I had put it in .product. But I hadn't. Either that or somebody else on the team moved it. Either way, it was above .product and .config, thus causing so many problems that I hadn't even realized. sigh Sorry |
Phil Webb commented No worries. We've all been there! |
Nick Williams opened SPR-9795 and commented
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:
And for my framework servlet configuration I used:
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:
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: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.
Affects: 3.1.2
0 votes, 5 watchers
The text was updated successfully, but these errors were encountered: