Spring启动缓存没有';行不通

Spring启动缓存没有';行不通,spring,spring-boot,spring-cache,Spring,Spring Boot,Spring Cache,我试图配置spring缓存,但该方法仍在执行。我有下面的代码,civilStatus缓存不工作。始终执行getCivilStatus()方法。有人知道原因吗 @Configuration @EnableCaching public class ApplicationConfig { @Autowired private SocioDemographicInfoService socioDemographicInfo; @Bean public CacheManager cacheManag

我试图配置spring缓存,但该方法仍在执行。我有下面的代码,civilStatus缓存不工作。始终执行getCivilStatus()方法。有人知道原因吗

@Configuration
@EnableCaching
public class ApplicationConfig {

@Autowired
private SocioDemographicInfoService socioDemographicInfo;


@Bean
public CacheManager cacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();
    cacheManager.setCaches(Arrays.asList(           
            new ConcurrentMapCache("civilStatus");

    return cacheManager;
}
}   



@Service
public class SocioDemographicInfoService {



@Cacheable(value="civilStatus")
public Map<String, String> getCivilStatus(){
    log.info("Retrieving civilStatus");
    Map<String, String> civilStatus = new HashMap<String, String>();
    BufferedReader br = null;
    String line = "";
    String cvsSplitBy = ",";
    try {
        ClassLoader classLoader = getClass().getClassLoader();
        File file = new File(classLoader.getResource("CatalogoEstadoCivil.csv").getFile());
        br = new BufferedReader(new FileReader(file));
        while ((line = br.readLine()) != null) {
            String[] cod = line.split(cvsSplitBy);
            civilStatus.put(cod[0].trim(), cod[1]);
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    return civilStatus;
}
}
@配置
@启用缓存
公共类应用程序配置{
@自动连线
私人社会人口信息服务社会人口信息;
@豆子
公共缓存管理器缓存管理器(){
SimpleCacheManager cacheManager=新的SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(
新的ConcurrentMapCache(“civilStatus”);
返回缓存管理器;
}
}   
@服务
公共类社会人口信息服务{
@可缓存(value=“civilStatus”)
公共地图getCivilStatus(){
日志信息(“检索状态”);
Map civilStatus=new HashMap();
BufferedReader br=null;
字符串行=”;
字符串cvsSplitBy=“,”;
试一试{
ClassLoader ClassLoader=getClass().getClassLoader();
File File=新文件(classLoader.getResource(“CatalogoEstadoCivil.csv”).getFile();
br=新的BufferedReader(新的文件读取器(文件));
而((line=br.readLine())!=null){
字符串[]cod=行分割(cvsSplitBy);
civilStatus.put(cod[0].trim(),cod[1]);
}
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}最后{
如果(br!=null){
试一试{
br.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
返回公民身份;
}
}

}

我相信您正在使用spring boot,并使用类似这样的类(如下所示)设置服务器。在同一个类上添加EnableCaching注释,并按如下所示定义CacheManager,而不是单独的配置类。这将确保在初始化类之前启用缓存

@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableCaching
@PropertySource(ignoreResourceNotFound = true, value = {"classpath:application.properties"})
@ImportResource(value = { "classpath*:spring/*.xml" })
public class MyBootServer{

public static void main(String args[]){
    ApplicationContext ctx = SpringApplication.run(MyBootServer.class, args);
}

@Bean(name="cacheManager")
public CacheManager getCacheManager() {
...// Your code
}
}

您的总体代码没有问题。我在中测试了您的配置,它可以正常工作。您不需要AOP和缓存复杂性。您的用例简单得多。只需创建一个方法,在启动时加载文件,并让您的
getCivilStatus
返回该映射。简单得多

@Service
public class SocioDemographicInfoService implements ResourceLoaderAware {

    private final Map<String, String> civilStatus = new HashMap<String, String>();

    private ResourceLoader loader;

    @PostConstruct
    public void init() {
        log.info("Retrieving civilStatus");
        Map<String, String> civilStatus = new HashMap<String, String>();
        BufferedReader br = null;
        String line = "";
        String cvsSplitBy = ",";
        Resource input = loader.getResource("classpath:CatalogoEstadoCivil.csv"));
        if (input.isReadable() ) {
            File file = input.getFile();
            br = new BufferedReader(new FileReader(file));
            try {
                while ((line = br.readLine()) != null) {
                    String[] cod = line.split(cvsSplitBy);
                    civilStatus.put(cod[0].trim(), cod[1]);
                }
            } catch (IOException e) {
                logger.error("Error reading file", e_;
            } finally {
                if (br != null) {
                    try { br.close() } catch( IOException e) {}
                }               
            }   
        }   
    }

    public Map<String, String> getCivilStatus() {
        return this.civilStatus;
    }

    public void setResourceLoader(ResourceLoader loader) {
        this.loader=loader;
    }

}
@服务
公共类SocialDemographicInfoService实现ResourceLoaderWare{
private final Map civilStatus=new HashMap();
私有资源加载器;
@施工后
公共void init(){
日志信息(“检索状态”);
Map civilStatus=new HashMap();
BufferedReader br=null;
字符串行=”;
字符串cvsSplitBy=“,”;
资源输入=loader.getResource(“classpath:CatalogoEstadoCivil.csv”);
if(input.isReadable()){
File File=input.getFile();
br=新的BufferedReader(新的文件读取器(文件));
试一试{
而((line=br.readLine())!=null){
字符串[]cod=行分割(cvsSplitBy);
civilStatus.put(cod[0].trim(),cod[1]);
}
}捕获(IOE异常){
logger.error(“读取文件时出错”,e;
}最后{
如果(br!=null){
请尝试{br.close()}捕获(IOE异常){}
}               
}   
}   
}
公共地图getCivilStatus(){
返回此.civilStatus;
}
公共void setResourceLoader(ResourceLoader){
this.loader=loader;
}
}

类似的东西应该可以工作。它在构建bean之后加载您的代码(此代码可能可以通过使用commons io之类的东西进行优化)。注意,我使用Springs
ResourceLoader
加载文件。

问题在于您的配置。您正在将带有缓存的bean自动连接到配置中。这会急切地实例化bean,而不会使其进行缓存后处理。非常感谢您的回答。我想在开头加载一个文件并缓存它。你知道我如何开发它吗?为什么你需要缓存?你可以自己做而不启用缓存。在你的
SocialDemographicInfoService
中添加一个方法,用
@PostConstruct
注释,加载文件并填充地图。不需要使用springs缓存抽象。我想要一个缓存,beca使用我需要调用getCivilStatus多次,我想缓存getCivilStatus(),将是最好的选择。您不需要它。只需在启动时加载文件以填充映射,然后让
getCivilStatus
返回该映射。您不需要增加缓存或AOP的复杂性。我尊重地不同意这种方法,因为它现在起作用,但限制了未来的增强功能,如生存时间、磁盘溢出和缓存框架通常提供的其他功能。此外,这将涉及许多不需要的锅炉板代码,这些代码本可以通过缓存框架来处理。没有锅炉板代码,代码与您编写的代码相同。因此,没有锅炉板。此外,如果您现在不需要某些东西,也不要为可能需要10年的东西增加复杂性从现在开始。不用使用
@PostConstruct
方法,你也可以让你的getter变懒,但是我真的不喜欢getter,它做的比刚刚得到的多。谢谢M.Deinum,我已经检查了你的代码。但是我在我的项目中加载了多个文件,因此我认为最好使用缓存。你是对的,我应该用h commons io。再次感谢。或者使用java8,这会更容易。我仍然不明白为什么需要一个复杂的缓存策略,因为它只会使事情复杂化,在这种情况下,一个懒散的getter就足够了。关于缓存的所有其他方面,这与您正在使用的缓存解决方案都不起作用。非常感谢您,您已经知道了是的。问题是我的配置,我已经更改了cacheManager,工作正常。