geneSummons
geneSummons

Reputation: 925

How to properly configure multiple component scans and "use default filters = false"

I'm developing a "new application" that wants to leverage code in an existing application, but I am having trouble getting "contextLoads()" to pass in the new application.

This configuration doesn't work:

//This is the main common library B application class:
@Configuration
@ComponentScan(basePackages=["com.acme.cacheb.lib"])
@Import(CacheACommonLibConfig.class)
@EnableConfigurationProperties 
class CacheBCommonLib {

}

//This  is the Config class Imported above:
@Configuration
@ComponentScan(basePackages=["com.acme.cachea.lib"], 
                             useDefaultFilters = false, 
                             includeFilters = [@ComponentScan.Filter(type = FilterType.CUSTOM, 
                             value = RescHandshakeTypeFilter.class)])
class CacheACommonLibConfig {

}

The error reported is an autowire failure:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cacheA_RepoImpl': Unsatisfied dependency expressed through field 'cacheA_Repo'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.acme.cachea.lib.jpa.repository.ICacheA_Repository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

I know my custom filter is matching everything I want (including that "missing" interface named ICacheA_Repository) and nothing I think I don't want. I suspect the error is because "useDefaultFilters = false" is in play and how the component scans are combined. If I do this

@ComponentScan(basePackages=["com.acme.cacheb.lib", "org.springframework"])

in the new main application class, the test runs longer before it fails reporting a different error, and I also get a fairly dire "Spring Warning"

** WARNING ** : Your ApplicationContext is unlikely to start due to a @ComponentScan of 'org.springframework'.

Any/All help greatly appreciated.

Upvotes: 0

Views: 1020

Answers (1)

geneSummons
geneSummons

Reputation: 925

I got "context loads" to pass in the B app by abandoning "include filtering" (with use default filters = false) of the A app dependency jar and switching to "exclude filtering" on the component scan. But after I "actually" got it working, I'm not sure I really needed to switch to "exclude filtering". The reason I think that is because at the end of my journey, I started seeing the same couple of errors I first saw which is why the "Thymeleaf View Resolver" is now excluded from auto configuration. (If only I had tried that when the error first appeared, rather than totally disabling auto configuration...)

The B app main class configuration is now configured like this:

@Configuration
@ComponentScan(basePackages=["com.acme.cacheb.lib"])
@Import(CacheACommonLibConfig.class)
@EnableAutoConfiguration(exclude=[WebMvcAutoConfiguration.class, ThymeleafAutoConfiguration.class])
@EnableConfigurationProperties
@EntityScan('com.acme.cacha.lib.jpa.entity')
@EnableJpaRepositories('com.acme.cacha.lib.jpa.repository')
//@EnableScheduling
class CacheBCommonLib {

}

and the Imported config class is now configured like this:

@Configuration
@ComponentScan(basePackages=["com.acme.cacha.lib.msg.auth",
                         "com.acme.cacha.lib.msg.emp",
                         "com.acme.cacha.lib.msg.processor",
                         "com.acme.cacha.lib.jpa"],
    excludeFilters = [@ComponentScan.Filter(type = FilterType.CUSTOM, value = CacheBExcludeCacheATypesFilter.class),
                      @ComponentScan.Filter(type = FilterType.REGEX,
                       pattern = "com.acme.cacha.lib.msg.processor.*"),
                      @ComponentScan.Filter(type = FilterType.REGEX,
                       pattern = "com.acme.cacha.lib.msg.auth.(sas|radius).*")
                     ])
class CacheACommonLibConfig {

}

Upvotes: 0

Related Questions