Avoid unwanted component scanning of Spring Configuration

I came through interesting problem on Stack Overflow. Brett Ryan had problem that Spring Security configuration was initialized twice. When I was looking into his code I spot the problem. Let me show show the code.

He has pretty standard Spring application (not using Spring Boot). Uses more modern Java servlet Configuration based on Spring’s AbstractAnnotationConfigDispatcherServletInitializer.

Pay attention to the component scanning in WebConfig. It is scanning package where all three classes are located. When you run this on servlet container, text “Spring Security init…” is written to console twice. It mean mean SecurityConfig configuration is loaded twice. It was loaded

During initialization of servlet container in method AppInitializer.getRootConfigClasses()

Remember that @Configuration classes are meta-annotated with @Component, so they are candidates for component-scanning!

So this is feature of Spring and therefore we want to avoid component scanning of Spring @Configuration used by Servlet configuration. Brett Ryan independently found this problem and showed his solution in mentioned Stack Overflow question:

I don’t like this solution. Annotation is too verbose for me. Also some developer can create new @Configuration class and forget to include it into this filter. I would rather specify special package that would be excluded from Spring’s component scanning.

I did not come to like that programming in annotations or XML. What’s wrong with plain Java, that will create the objects and set dependencies. The annotation approach is not debuggable, call hierarchy will not show you dependencies, magic things happen and obvious things sometimes don’t. You find five solutions to your problem on stackoverflow, but in your case the sixth is correct.

Hi Vilo,
This is not about programming with annotations or XML. Nearly all frameworks nowadays are using annotations. It’s normal part of Java language since Java 5 I think. When you aren’t using frameworks, you are creating your own framework. Creating your own framework is waste of time and money in most cases. Spring or Java EE provides huge amount of abstractions on top of well established technologies, so that you can glue them very easily together. With spring-data-rest you can specify only your JPA entities and you can have full REST API backend. How much coding, wasteful and error prone boilerplate code that would be with plain servlets?
I was working for Kios, where you are Architect now and know that you have internal framework called KTF.
Have few questions for you? What is your unit test coverage? How many integration tests are being executed every day? Which continuous integration server are you using? What static code analyzers or code quality tools are being applied on your code? Are you writing test before actual implementation?

If you would be able to respond these questions positively, you would already know that debugging is needed very rarely.

The solution hides the problem. A @Configuration class that extends WebSecurityConfigurerAdapter and uses @EnableWebMvcSecurity is not a root application context and hence returning it from getRootConfigClasses() is bad design. Root context should not contain any web related beans – that’s what’s the getServletConfigClasses() is specifically meant for.