【问题标题】:Why is this cache not getting evicted?为什么这个缓存没有被驱逐?
【发布时间】:2017-02-20 12:19:06
【问题描述】:

AdminSOAPRunner:

@Component
public class AdminSOAPRunner {

    private static final Logger LOGGER = LoggerFactory.getLogger(AdminSOAPRunner.class);

    private String userId;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    @Autowired
    private AdminAuth adminAuthenticator;

    @Autowired
    private AdminBean adminBean;

    private AccountService accountService;


    private void setBindingProviderByAccountService() {
        WSBindingProvider bindingProvider = (WSBindingProvider) this.accountService;
        bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, adminBean.getAccountUrl());
        LOGGER.info("Endpoint {}", adminBean.getAccountUrl());
    }

    private RequestInfo getRequestInfo() {

        RequestInfo requestInfo = new RequestInfo();

        requestInfo.setAppName(adminBean.getAppName());
        requestInfo.setUserId(this.getUserId());
        requestInfo.setTrace(UUID.randomUUID().toString());
        return requestInfo;

    }

    public List<ApplyAccountResult> getAccounts(ApplyAccountRequest request) {
        AccountService_Service service = null;

        URL serviceWSDL = AccountService_Service.class.getResource("/Account-service/Account-service.wsdl");
        service = new AccountService_Service(serviceWSDL);

        SOAPHandlerResolver SOAPHandlerResolver = new SOAPHandlerResolver();
        SOAPHandlerResolver.getHandlerList().add(new SOAPHandler(this.adminAuthenticator));
        service.setHandlerResolver(SOAPHandlerResolver);

        if (accountService == null) {
            accountService = service.getAccountService();
        }

        setBindingProviderByAccountService();

        ApplyAccountAccountResponse response = null;
        LOGGER.info("Making a SOAP request.");
        response = AccountService.applyAccount(request, getRequestInfo(), new Holder<ResponseInfo>());
        LOGGER.info("SOAP request completed.");
        return response.getApplyAccountResults();
    }

SOAPHandlerResolver:

public class SOAPHandlerResolver implements HandlerResolver {

    @SuppressWarnings("rawtypes")
    private List<Handler> handlerList;

    public SOAPHandlerResolver() {
        this.handlerList = null;
    }

    @SuppressWarnings("rawtypes")
    public List<Handler> getHandlerList() {
        if (this.handlerList == null) {
            this.handlerList = new ArrayList<>();
        }
        return this.handlerList;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public List<Handler> getHandlerChain(PortInfo portInfo) {
        List<Handler> handlerChain = new ArrayList<>();
        if (this.handlerList == null || this.handlerList.isEmpty()) {
            this.handlerList = new ArrayList<>();
            this.handlerList.add(new SOAPHandler(null));
        }
        handlerChain.addAll(this.handlerList);
        return handlerChain;
    }
}

SOAPHandler

public class SOAPHandler implements SOAPHandler<SOAPMessageContext> {

    private AdminAuth adminAuth;
    private static final Logger LOGGER = LoggerFactory.getLogger(SOAPHandler.class);

    public MosaicOnboardSOAPHandler(AdminAuth adminAuth) {
        if (adminAuth == null) {
            adminAuth = new AdminAuth();
            LOGGER.info("AdminAuth found null. Creating new adminAuth instance.");
        }
        this.adminAuth = adminAuth;
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty) {
            @SuppressWarnings("unchecked")
            Map<String, List<String>> headers = (Map<String, List<String>>) context.get(MessageContext.HTTP_REQUEST_HEADERS);
            if (headers == null) {
                headers = new HashMap<>();
                context.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
            }
            List<String> cookie = headers.get("Cookie");
            if (cookie == null) {
                cookie = new ArrayList<>();
                headers.put("Cookie", cookie);
            }
            cookie.add(this.adminAuth.getToken());
        }
        return true;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return false;
    }

    @Override
    public void close(MessageContext context) {

    }

    @Override
    public Set<QName> getHeaders() {
        return null;
    }
}

管理员身份验证:

@Component
public class AdminAuth {

    @Autowired
    private AdminBean adminBean;

    private static final Logger LOG = LoggerFactory.getLogger(Admin.class);
    private String token;

    private void generateToken() {

        try {
            AdminTokenHelper adminTokenHelper = new AdminTokenHelper(adminBean.getAutheticationServerURL(), adminBean.getLicense());


            token = adminTokenHelper.getToken(adminBean.getUsername(), adminBean.getPassword().toCharArray());

            LOG.info("Token generation successful");
        } catch (Exception ex) {
            ex.printStackTrace();
            LOG.error("Token generation failed");
            LOG.error(ex.getMessage());
            throw new RuntimeException("Token generation failed", ex);
        }
    }

    @Cacheable(value = "tokenCache")
    public String getToken() {
        LOG.warn("Token not available. Generating a new token.");
        generateToken();
        return token;
    }
}

ehcache.xml

 <cache name="tokenCache" maxEntriesLocalHeap="1" eternal="false" timeToIdleSeconds="895" timeToLiveSeconds="895" memoryStoreEvictionPolicy="LRU"/>

应用

@EnableCaching
@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
        return application.sources(Application.class).profiles(determineEnvironmentProfile());
    }
}

在 AdminAuth 中,它使用功能用户来生成令牌。为身份验证生成的令牌将在 15 分钟后过期。所以我的目的是编写缓存,以便所有来自 ui 的调用都可以使用相同的令牌,而不管实际用户如何。所以我将时间设置为 14:55 来生成新的令牌。现在问题在 15 分钟后出现,并且缓存不会驱逐旧令牌,因此调用使用旧的和过期的令牌并且它失败了。 我尝试了不同的驱逐策略,如 LRU、LFU、FiFO,但没有任何效果。调用来自 ui 通过 Spring Boot 1.3 中的 tomcat 容器。

为什么没有被驱逐?我错过了什么?任何帮助表示赞赏

【问题讨论】:

  • 你能发布你的 Spring 缓存配置吗?
  • @starf 我编辑了代码。请在上面查看。
  • 您使用的是哪个版本的 Ehcache?您是否为 (Ehcache3) org.ehcache:ehcache 等添加了依赖项?
  • 版本 2.8.3。我有 net.sf.ehcache 和 spring-support-context 依赖项。在使用@EnableCaching 时,我使用的是 xml。应该缺少映射吗?我真的很困惑。
  • 拥有 ehcache.xml 是可以的,只要它位于类路径的根目录中 - 即,如果使用 maven,则位于 src/main/resources 中。您应该添加 org.springframework.boot:spring-boot-starter-cache 并删除 spring-support-context。

标签: java spring caching


【解决方案1】:

@Cacheable(value = "tokenCache") 替换为@Cacheable("tokenCache")

【讨论】:

  • 这没什么区别。这实际上是一回事。
【解决方案2】:

来自cmets:

缺少对spring-boot-starter-cache 的依赖。这阻止了 Spring Boot 自动配置CacheManager。添加此依赖项后,缓存配置就起作用了。

http://docs.spring.io/spring-boot/docs/1.3.x/reference/html/boot-features-caching.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2014-10-12
    • 1970-01-01
    相关资源
    最近更新 更多