Java Config.class中的CacheManager bean定义导致NoSuchBeanDefinitionException
我有一个Spring服务,它检查数据库条目。为了最小化我的存储库调用,两个find方法都是“@Cacheable”。但当我尝试在配置类具有CacheManager bean定义的情况下初始化服务bean时,我得到以下NoSuchBeanDefinitionException:Java Config.class中的CacheManager bean定义导致NoSuchBeanDefinitionException,java,eclipselink,spring-data-jpa,spring-cache,Java,Eclipselink,Spring Data Jpa,Spring Cache,我有一个Spring服务,它检查数据库条目。为了最小化我的存储库调用,两个find方法都是“@Cacheable”。但当我尝试在配置类具有CacheManager bean定义的情况下初始化服务bean时,我得到以下NoSuchBeanDefinitionException: Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'foo.med
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'foo.mediacode.directory.MediaCodeDirectoryService' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:353)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1093)
at foo.mediacode.directory.MediaCodeDirectoryService.implementation(MediaCodeDirectoryService.java:63)
at foo.campaigntree.directory.CampaignTreeDirectoryService.<init>(CampaignTreeDirectoryService.java:18)
... 15 more
服务
....
public class MediaCodeDirectoryService implements MediaCodeDirectoryServiceApi {
...
@Autowired
private MediaCodeDirectoryRepository repo;
@SuppressWarnings("resource")
public static MediaCodeDirectoryServiceApi implementation() {
if (INSTANCE == null) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MediaCodeDirectoryServiceConfig.class);
INSTANCE = ctx.getBean(MediaCodeDirectoryService.class);
}
return INSTANCE;
}
...
存储库
...
@Repository
public interface MediaCodeDirectoryRepository extends CrudRepository<MediaCodeDao, Integer> {
@Cacheable("mediaCodeMappingRegexes")
@Query("SELECT m FROM #{#entityName} m WHERE (m.fooId = :fooId) AND (m.isRegex = :isRegex) ORDER BY (m.orderId DESC, m.id ASC)")
List<MediaCodeDao> findByfooIdAndIsRegexOrderByOrderIdDescAndIdAsc(@Param("fooId") int fooId, @Param("isRegex") boolean isRegex);
@Cacheable("mediaCodeMappings")
List<MediaCodeDao> findByMediaCode(String MediaCode, Pageable pageable);
}
我避免了NosuchBeanDefinition异常,但遇到了另一个异常
这里有人知道这可能是什么原因吗?我的配置中有什么遗漏吗?谢谢 缓存通过AOP应用。对于AOP,Spring使用基于代理的方法,默认方法是创建基于接口的代理
public class MediaCodeDirectoryService implements MediaCodeDirectoryServiceApi {... }
在运行时使用此类定义,您将获得一个动态创建的类(Proxy$51
或类似的类),该类实现了所有接口,但它不是MediaCodeDirectoryService
。但是,它是一个MediaCodeDirectoryServiceApi
有两种方法可以解决这个问题,一种是程序到接口(因为已经定义了接口,所以无论如何都应该这样做),而不是具体的类,另一种是使用基于类的代理
第一个选项涉及在直接@Autowire
的位置更改代码,或者获取MediaCodeDirectoryService
的实例以使用MediaCodeDirectoryServiceApi
(您应该已经这样做了,为什么还要定义接口)。现在您将注入代理,一切都将正常工作
第二个选项涉及在@EnableCaching
注释上设置proxyTargetClass=true
。然后,您将得到一个基于类的代理,而不是基于接口的代理
@EnableCaching(proxyTargetClass=true)
您应该编程到接口而不是具体的类。。。因此,不要在代码中使用
MediaCodeDirectoryService
而是使用MediaCodeDirectoryServiceApi
。在另一个节点上,您的代码是危险的,您永远不应该调用new*ApplicationContext
,因为您基本上是在反复创建应用程序。如果你在很多地方都有这段代码,你最终会遇到内存问题、事务问题、奇怪的并发性问题(当然,如果你想让这些问题自由出现,但我强烈建议你不要这样做!)。非常感谢你清晰而详细的回答。之后,我做了一些研究,发现了为什么要自动连接接口而不是类的一般解释
public class MediaCodeDirectoryService implements MediaCodeDirectoryServiceApi {... }
@EnableCaching(proxyTargetClass=true)