package com.wb.domainserver.security.config; import com.github.benmanes.caffeine.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine; import com.wb.domainserver.realm.RealmResolver; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.caffeine.CaffeineCacheManager; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @Configuration @EnableCaching public class CacheConfig { private final ApplicationContext applicationContext; public CacheConfig(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Bean public CaffeineCacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(caffeineCacheBuilder()); cacheManager.setCacheLoader(cacheLoader()); return cacheManager; } @Bean public Caffeine caffeineCacheBuilder() { return Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(100); } @Bean public CacheLoader cacheLoader() { return new CacheLoader<>() { @Override public Object load(Object key) { return loadAsync(key).join(); } @Override public CompletableFuture asyncReload(Object key, Object oldValue, Executor executor) { return loadAsync(key); } private CompletableFuture loadAsync(Object key) { String hostUrl = (String) key; RealmResolver realmResolver = applicationContext.getBean(RealmResolver.class); return realmResolver.resolveRealmInternalDirect(hostUrl); } }; } }