2014-12-13 82 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