Spring component scan filter

I currently live in jar/dependency hell. At one point there was about 5 jars for everything and statements like "We need to break things apart" swung the pendulum all the way to the other side. Left or the right, you pick :). Recently I was working on a project where we have old spring xml configuration meshed with new java config. There was some conflicting configuration classes so I needed to use a filter to customize scanning.

Filter types

After digging into spring reference documentation there is a filter system that allows you to exclude elements during the component scan process. The following filter types are available:

Filter TypeExample ExpressionDescription
annotationorg.example.SomeAnnotationAn annotation to be present at the type level in target components.
assignableorg.example.SomeClassA class (or interface) that the target components are assignable to (extend/implement).
aspectjorg.example..*Service+An AspectJ type expression to be matched by the target components.
regexorg\.example\.Default.*A regex expression to be matched by the target components class names.
customorg.example.MyTypeFilterA custom implementation of the org.springframework.core.type .TypeFilter interface.

Custom component scan using java config

The documentation shows the xml version but since we are on the path to eliminate XML, I wanted this in my ApplicationConfig java configuration file. When you go through this process of reverse engineering your xml to java config. The java config route uses the ComponentScan.Filter annotation and it contains 3 optional elements.

Element typeDescription
valueThe pattern which is an alternative to the Class element that allows you to specifiy a pattern.
typeDefined by the [FilterType Enum](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/FilterType.html) it specifies the type to use.
valueThe classes or classes that should be used with the filter

The java config and the associated xml configuration is below:

Java configXML
@Configuration
@Import({
    com.levelup.SomeOtherProjectConfiguration.class
})
@ImportResource({
    "classpath:com/levelup/applicationContext.xml"
})
@Configuration
@ComponentScan(
    excludeFilters = @Filter(type=FilterType.ASSIGNABLE_TYPE, value={SomeotherConfig.class}), 
    basePackages = { 
      "com.levelup"
    }
)
MyConfigClass {
    //...
}
<beans>
    <context:component-scan base-package="com.levelup">
        <context:exclude-filter type="assignable"
                expression="com.levelup....SomeotherConfig"/>
    </context:component-scan>
</beans>

Spring is very configurable and while this shows off how filter components during auto scanning, there is also way to include. See spring docs for more details.