2014-12-13 124 views
1

我试图配置Spring缓存,但该方法仍然执行。我有下面的代码,并且civilStatus缓存不起作用。方法getCivilStatus()始终执行。有人知道原因吗?Spring Boot缓存不起作用

@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; 
} 
} 

}

+0

问题在于你的配置。您将自动将您的bean与高速缓存连接到配置中。这个实例化这个bean并且不会为了缓存而进行后期处理。 – 2014-12-13 11:55:09

+0

非常感谢你的回答。我想在开始时加载一个文件并缓存它。你知道我该怎么开发它? – nole 2014-12-13 12:07:51

+1

为什么你需要缓存?你可以自己做,而无需启用缓存。在'@ PostConstruct'注释的'SocioDemographicInfoService'中添加一个方法,该方法加载文件并填充地图。没有必要使用弹簧缓存抽象。 – 2014-12-13 12:45:07

回答

1

你不需要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; 
    } 

} 

这样的事情应该工作。它在构造bean之后加载你的代码(这个代码可以通过使用类似commons-io的东西来优化)。注意我使用Springs ResourceLoader加载文件。

+0

我非常不同意这种方法,因为它符合今天的目的,但限制将来的增强功能,例如生存时间,溢出到磁盘和通常缓存框架提供的其他功能。此外,这将涉及很多不必要的锅炉板代码,这些代码将通过缓存框架来处理。 – kamoor 2014-12-13 18:18:38

+0

没有锅炉板代码,代码与您所写的代码相同。所以没有样板。此外,如果您现在不需要某些东西,请不要为10年后可能需要的东西增加复杂性。不是使用'@ PostConstruct'方法,你也可以让你的getter很懒,但是我真的不喜欢get的getter。 – 2014-12-14 11:18:08

+0

感谢M.Deinum,我检查了你的代码。但是我在我的项目中加载了多个文件,因此我认为最好使用缓存。你说得对,我应该用commons-io来优化我的代码。再次感谢你。 – nole 2014-12-15 08:10:53

1

我相信你正在使用的弹簧引导和使用一类是这样的(如下)设置服务器。在同一个类上添加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 
} 
} 

你的所有代码没有错。我在my spring boot sample code中测试了你的配置,它的工作原理是

+0

非常感谢,你是对的。问题是我的配置,我已经改变了cacheManager并且工作正常。 – nole 2014-12-15 08:07:18

相关问题