【问题标题】:Spring Cache in MVC - Possible to lookup with autowiring?MVC 中的 Spring Cache - 可以使用自动装配进行查找吗?
【发布时间】:2019-11-20 07:56:14
【问题描述】:

我看到当应用程序启动时我的单例缓存被创建

DEBUG 创建 CGLIB 代理:目标源是 SingletonTargetSource for 目标对象 [com.abc.xyz.util.CacheUtil@14e3dd3] 调试无法 对建议的方法应用任何优化:public java.util.Map

但是我如何使用自动装配来查找值,因为当我尝试时,它不会命中创建的单例并创建一个新的 CacheUtil 实例。

CacheUtil.java [这个类被@Component注解]

    public Map getSelectOptions(String codeType) {
        System.out.println("Cache Breached!!!");
        HashMap selectOpts = new HashMap();
        Vector<MyTableDO> vCodeMap = null;
        vCodeMap = MyTableDO.getCodesFromDatabase(codeType, "LookupCacheUtil"); 


        if(vCodeMap == null || vCodeMap.size() == 0) return selectOpts;

        vCodeMap.forEach(codeMap -> selectOpts.put(codeMap.getCodeValue(), codeMap.getCodeDesc()));

        return selectOpts;
    }

我的 spring 配置 xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.abc.xyz" />
    <context:annotation-config />
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

   <bean id="cacheUtil" class="com.abc.xyz.util.CacheUtil" />
</beans>

类调用缓存方法

  @Autowired
  @Qualifier("cacheUtil")
  protected CacheUtil cacheUtil;

  public Map getSelectOptions(String codeType) {

      AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyApplication.class); 
      //ctx.refresh();
      CacheUtil lkp = (CacheUtil) ctx.getBean(CacheUtil.class); 
      ctx.close();   

      System.out.println("App Context lookupCacheUtil -"+lkp); // Not the same object of Spring Cache and comes to be new instance on every call
      System.out.println("Autowired lookupCacheUtil -"+cacheUtil); // Always comes to be NULL

      return lkp.getSelectOptions(codeType);  
  }

}

MyApplication 类

@SpringBootApplication
@EnableCaching
public class MyApplication extends SpringBootServletInitializer{


    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyApplication.class);
    }

    @Override
    public void onStartup(ServletContext container) {
        XmlWebApplicationContext context = new XmlWebApplicationContext();
        context.setConfigLocation("/WEB-INF/config/spring-servlet.xml");

        //using servlet 3 api to dynamically create spring dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("spring", new DispatcherServlet(context));
        dispatcher.setLoadOnStartup(2);
        dispatcher.addMapping("/");
    }

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

}

【问题讨论】:

  • 你能解释一下“使用自动装配查找”是什么意思吗?
  • Spring-Cache创建的CacheUtil的Singleton是否可以自动装配并使用?
  • 如果您的 CacheUtil 类被声明为 Spring bean,您应该能够自动装配它。也许发布更多代码让我们了解上下文。
  • 我添加了更多代码。请尽可能查看。

标签: spring spring-mvc spring-cache


【解决方案1】:

详细分析后,我对 Autowired 的理解更加细化了。感谢link

就我而言,我在表单 bean 上自动装配了“CacheUtil”。似乎表单bean没有由spring管理,或者至少在这种情况下。同样的 autowired 在由 Spring 管理的控制器中正常工作。

所以我通过从应用程序上下文中获取 CacheUtil 的 Spring Cache“代理”版本来解决问题。下面的代码 sn-p 应该会有所帮助(方法 getInstance()):

import org.springframework.beans.BeansException;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component("MyCache")
public class CacheUtil implements ApplicationContextAware{

    private static ApplicationContext appContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // TODO Auto-generated method stub
        appContext = applicationContext;
    }
    /**
     * Method to fetch the shared instance of the Spring Cache Object that helps reach the 
     * Cache that resides in Application Context.
     * 
     * @return Singleton shared instance of the Spring Cache Proxy of this class CacheUtil 
     */
    public static CacheUtil getInstance() {
        CacheUtil appCache = appContext.getBean("MyCache", CacheUtil.class);        
        if(appCache != null) return appCache;

        return new CacheUtil();
    }

【讨论】:

    猜你喜欢
    • 2018-09-15
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 2014-01-20
    相关资源
    最近更新 更多