Spring 缓存代理不适用于 xml 中加载的 beans 与 @Configuration 中加载的那些

Spring Caching proxy not applying to beans loaded in xml vs those loaded in @Configuration

是否可以通过 <context:component-scan/> 将 bean 加载到 xml 文件中,并由 @Coniguration 注释 class 代理,该文件具有 @EnableCaching 并声明 SimpleCacheManager?对于我正在使用的大型应用程序,这将是最简单的方法,我的最终偏好是将其全部转换为配置 class,但这需要做更多的工作,而且几乎没有单元测试对于这个应用程序 -.- ,有些东西会完全崩溃。另一种选择是在 xml 中声明缓存,这很好用,但我觉得这是倒退了一步。

注意:<context:annotation-config/> 在单独的 xml 文件中声明 'integration.xml' 我把它放回 applicationContext.xml 但它没有影响任何东西。

缓存声明和通过 @EnableCaching 启用缓存已移至下方 java class 一段时间前,我认为没有人注意到它停止工作。所以我想让它以最好的方式再次工作。

应用程序上下文(为简洁起见进行了编辑)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:task="http://www.springframework.org/schema/task"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:cache="http://www.springframework.org/schema/cache"
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
    "
        >

    <util:properties id="properties" location="classpath:config.properties"/>
    <context:property-placeholder properties-ref="properties"/>

    <!-- TODO: Replace this with MethodInvokingBean - we don't actually *want* a ConfigFactory instance -->
    <bean id="configFactory" class="net.adl.service.ConfigFactory">
        <property name="properties" ref="properties" />
    </bean>

    <!-- Enable Caching -->
    <cache:annotation-driven proxy-target-class="true"/>

    <!-- Declaring the cache manager and caches here works, but I feel is a step backwards to put them back in the XML config -->
    <context:component-scan base-package="
        net.adl.quartz,
        net.adl.config,
        net.adl.dao,
        net.adl.service,
        net.adl.audit,
        net.adl.diagnostic,
        net.adl.loader,
        net.adl.loader"/>


    <!-- add support for @Scheduled -->
    <task:scheduler id="taskScheduler" pool-size="10"/>
    <task:executor id="taskExecutor" pool-size="10"/>

    <!-- Used for real time monitoring of folders for data loads -->
    <task:executor id="realTimeAutoLoaderExecutor" pool-size="1"/>
    <task:annotation-driven scheduler="taskScheduler" executor="taskExecutor"/>

    <!-- enable @Transactional annotations -->
    <bean id="transactionAdvice" class="net.adl.aop.TransactionAdvice"/>
    <!--<bean id="profiler" class="net.adl.util.Profiler"/>-->

    <aop:aspectj-autoproxy proxy-target-class="true">
        <aop:include name="transactionAdvice"/>
        <!--<aop:include name="profiler"/>-->
    </aop:aspectj-autoproxy>

    <!-- set system properties -->
    <bean id="systemPrereqs" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <!--
            "systemProperties" is predefined; see:
            http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html#expressions-beandef-xml-based
        -->
        <property name="targetObject" value="#{@systemProperties}"/>
        <property name="targetMethod" value="putAll"/>
        <property name="arguments">
            <util:properties>
                <prop key="net.sf.ehcache.skipUpdateCheck">true</prop>
                <prop key="org.terracotta.quartz.skipUpdateCheck">true</prop>
            </util:properties>
        </property>
    </bean>

    <!-- Exception translation bean post processor -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
    <bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/>

    <bean id="versionInfo" class="net.adl.util.VersionInfo">
        <property name="versionFilePath" value="${labmatrix.home}/version-info.txt"/>
    </bean>

    <!-- Here is where we call in the <context:annotation-config/>, not sure why its done in a separate file -->
    <import resource="resources/spring/integration.xml"/>

</beans>

Integration.xml -- 我认为这个想法是更多特定于部署的配置选项可以放在这个

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    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-3.1.xsd
    "
>

    <context:annotation-config/>

</beans>

方法缓存配置Class

package net.adl.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;

@Configuration
@EnableCaching
public class MethodCacheConfiguration {
    public static final String STUDY_CONFIG = "config.studies";
    public static final String ACCESS_CONFIG = "config.access";
    public static final String WORKFLOW_CONFIG = "config.workflows";
    public static final String PROCESS_CONFIG = "config.processes";
    public static final String QUERY_CONFIG = "config.queries";
    public static final String AUTOLOADER_CONFIG = "config.autoloader";
    public static final String LOCALIZATION = "localization";
    public static final String FACTORY_CONFIG = "config.factories";


    /**
     * Configures the cacheManager bean for @Cacheable annotation support
     */
    @Bean
    public CacheManager cacheManager() {
            SimpleCacheManager cacheManager = new SimpleCacheManager();

            cacheManager.setCaches(Arrays.asList(
                new ConcurrentMapCache(STUDY_CONFIG),
                new ConcurrentMapCache(ACCESS_CONFIG),
                new ConcurrentMapCache(WORKFLOW_CONFIG),
                new ConcurrentMapCache(PROCESS_CONFIG),
                new ConcurrentMapCache(QUERY_CONFIG),
                new ConcurrentMapCache(AUTOLOADER_CONFIG),
                new ConcurrentMapCache(LOCALIZATION),
                new ConcurrentMapCache(FACTORY_CONFIG)
            ));

            return cacheManager;
    }
}

编辑:修复了复制粘贴重新格式化拼写错误

<cache:annotation-driven /> and @EnableCaching are equal you can have only one (maybe it can be source of your trouble) Can you provide example of code where you are actually using caching? Which bean should use cache feature.

答案由 chalimartines 提供