2017-01-17 1 views
1

私はSpringを使用しています。私はアプリケーションを起動する前にいくつかのデータをキャッシュしたいと思います。スタートアップ時に@Cacheableを使用しないSpringキャッシュ@PostConstruct

@PostConstructを使用して@Serviceメソッド(@Cacheableという注釈が付けられています)を呼び出すために、他のポストでいくつかのソリューションが見つかりました。 How to load @Cache on startup in spring? 私はそれをしましたが、アプリケーションの開始後、このサービスメソッドを呼び出すRESTエンドポイントを呼び出すと、別の時間にデータベース要求を送信しています(まだキャッシュされていません)。 2回目のエンドポイントへのリクエストを送信すると、データがキャッシュされます。

@PostConstructのServiceメソッドを呼び出すと、データベースのデータがキャッシュされませんでした。

アプリを起動する前にデータをキャッシュすることはできますか?どうやってやるの?以下は私のコードの断片です。

@RestController 
class MyController { 

    private static final Logger logger = LoggerFactory.getLogger(MyController.class); 

    @Autowired 
    MyService service; 

    @PostConstruct 
    void init() { 
     logger.debug("MyController @PostConstruct started"); 
     MyObject o = service.myMethod("someString"); 
     logger.debug("@PostConstruct: " + o); 
    } 

    @GetMapping(value = "api/{param}") 
    MyObject myEndpoint(@PathVariable String param) { 
     return service.myMethod(param); 
    } 

} 


@Service 
@CacheConfig(cacheNames = "myCache") 
class MyServiceImpl implements MyService { 

    @Autowired 
    MyDAO dao; 

    @Cacheable(key = "{ #param }") 
    @Override 
    public MyObject myMethod(String param) { 
     return dao.findByParam(param); 
    } 
} 


interface MyService { 
    MyObject myMethod(String param); 
} 


@Repository 
interface MyDAO extends JpaRepository<MyObject, Long> { 
    MyObject findByParam(String param); 
} 


@SpringBootApplication 
@EnableConfigurationProperties 
@EnableCaching 
public class MyApplication { 
    public static void main(String[] args) { 
     SpringApplication.run(MyApplication.class, args); 
    } 

    @Primary 
    @Bean 
    public CacheManager jdkCacheManager() { 
     return new ConcurrentMapCacheManager("myCache"); 
    } 
} 
+1

'@のPostConstruct'でこれをやろうとしているが、一般的に悪い考えであることはありません(早期に実行される可能性がありますプロキシが作成されているため、AOPは適用されていません)。 'ContextRefreshedEvent'をリッスンする' ApplicationListener'でこれを行う方が良いでしょう。これは、すべてが開始されたことを知らせるトリガーで、キャッシングメソッドを呼び出すことができます。 –

+0

@ M.Deinum okですが、RESTエンドポイントが開始されてリクエストを受信する前にキャッシュを開始する必要があります。どうやってやるの? – user3626048

+1

dispatcherservletが起動するとすぐにリスニングしています...前述のように、安全な方法で 'ApplicationListener'を使用します。 –

答えて

0

@PostConstructがあなたのケースで動作します。 @PostConstructアノテーションを持つメソッドは、メソッドBeanがインスタンス化された直後に呼び出されます。

しかし、他のBeanに依存し、アプリケーションコンテキストが完全に開始した後でメソッドを呼び出した場合は、あなたはそのような新しいBeanを作成することができます。

@Component 
public class MyListener 
     implements ApplicationListener<ContextRefreshedEvent> { 

    public void onApplicationEvent(ContextRefreshedEvent event) { 
     //Here call your method of cache 
     // Your methode will be called after the application context has fully started 
    } 
} 
0

春1.3以降で:

@Component 
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> { 

@Autowired 
private MyService service; 

    /** 
    * This event is executed as late as conceivably possible to indicate that 
    * the application is ready to service requests. 
    */ 
    @Override 
    public void onApplicationEvent(final ApplicationReadyEvent event) { 

    service.myMethod(); 

    } 

} 
関連する問題