我们的顶级@ComponentScan扫描一个程序包,该程序包又包含@ComponentScan,该程序包选择了我们要忽略的@Configuration类。在顶层@ComponentScan上使用excludeFilters似乎不能让我们排除我们要避免的@Configuration。
我们正在尝试向我们的spring项目添加一个依赖项,并使用@ComponentScan引入所需的库。
但是,我们要排除一个@Configuration类,因为它包含一个使用了Spring 4中不推荐使用的GuavaCache的@Bean。我们使用的是Spring 5,因此,如果尝试使用该类,请获取NoClassDefFoundError。
使用较新的spring 5缓存很容易创建我们自己的实现,但是无法弄清楚如何排除现有的@Configuration。我们需要扫描的基本程序包不是包含不良类的程序包,而是扫描包含其他带有@ComponentScan批注的类的程序包,这会使它被拾取。
我们在顶级spring-boot应用程序类(位于thirdparty.infrastructure.requestcontext中的类)上尝试过的注释然后是@ComponentScan以查找要排除的JwtCacheConfig
@SpringBootApplication
@ComponentScan(basePackages = {
"com.ourpackage",
"thirdparty.infrastructure.requestcontext"},
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX,
pattern = "fourthparty\\.common\\.jwtvalidation\\.domain\\.config\\..*"))
public class MyApplication
也尝试过:
@SpringBootApplication
@ComponentScan(basePackages = {
"com.ourpackage",
"thirdparty.infrastructure.requestcontext"},
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
classes = fourthparty.common.jwtvalidation.domain.config.JwtCacheConfig.class))
public class MyApplication
要忽略的类:
package fourthparty.common.jwtvalidation.domain.config
import com.google.common.cache.CacheBuilder
import org.springframework.beans.factory.annotation.Value
import org.springframework.cache.Cache
import org.springframework.cache.annotation.EnableCaching
import org.springframework.cache.guava.GuavaCache
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.util.concurrent.TimeUnit
@Configuration
@EnableCaching
class JwtCacheConfig {
@Value('${px.cache.jwtPublicKeys.maximumSize:50}')
Integer maximumCacheSize
@Value('${px.cache.jwtPublicKeys.expireAfterWrite:1440}')
Integer expirationTime
@Bean
Cache jwtPublicKeyCache(){
return new GuavaCache('jwtPublicKeys', CacheBuilder.newBuilder()
.maximumSize(maximumCacheSize).expireAfterWrite(expirationTime, TimeUnit.MINUTES).build(), true)
}
}
我们要设置的课程
package com.ourpackage.config
import java.time.Duration
import com.github.benmanes.caffeine.cache.Caffeine
import org.springframework.beans.factory.annotation.Value
import org.springframework.cache.Cache
import org.springframework.cache.annotation.EnableCaching
import org.springframework.cache.caffeine.CaffeineCache
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
@Configuration
@EnableCaching
class MyJwtCacheConfig
{
@Value('${px.cache.jwtPublicKeys.maximumSize:50}')
Integer maximumCacheSize
// cache it for 24 hours (60 min * 24 hours)
@Value('${px.cache.jwtPublicKeys.expireAfterWrite:1440}')
Integer expirationTime
@Bean
Cache myJwtPublicKeyCache(){
def cacheMap = Caffeine.newBuilder()
.expireAfterWrite(Duration.ofMinutes(expirationTime))
.maximumSize(maximumCacheSize)
.build()
return new CaffeineCache('jwtPublicKeys', cacheMap, true)
}
}
每次尝试启动应用程序时,我们都要排除的类仍会被拾取,然后得到:
java.lang.NoClassDefFoundError: org/springframework/cache/guava/GuavaCache
...
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'cacheManager' defined in class path resource [org/springframework/boot/autoconfigure/cache/GenericCacheConfiguration.class]:
Unsatisfied dependency expressed through method 'cacheManager' parameter 0;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'jwtPublicKeyCache' defined in class path resource
[fourthparty/common/jwtvalidation/domain/config/JwtCacheConfig.class]:
Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cache.Cache]:
Factory method 'jwtPublicKeyCache' threw exception;
nested exception is java.lang.NoClassDefFoundError: org/springframework/cache/guava/GuavaCache