如何强制排除递归@ComponentScan拾取的Spring @Configuration

时间:2019-06-12 11:48:39

标签: spring spring-boot spring-cache

我们的顶级@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

0 个答案:

没有答案