当前位置: 首页 > 知识库问答 >
问题:

使用@Cacheable方法创建实现ApplicationListener的bean时出错

万俟高峻
2023-03-14

我们在部署应用程序时遇到了问题,经过一段时间的研究,我们找到了问题的根源,但我们不知道为什么会发生这种情况。

在Spring上下文初始化时,应用程序尝试将bean“bar”连接到bean“foo”上Bar’bean实现了接口ApplicationListener,并且还有一个@Cacheable方法。由于某种原因,我们不知道,bean创建出现了崩溃。删除@Cacheable或使bean不是ApplicationListener的实例,应用程序运行正常。

可能是对ApplicationListener和/或@Cacheable的误解,但发生此错误的原因是什么?为什么“酒吧豆”是非法的?Spring版本是3.2.9。

Spring上下文文件

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

<bean id="applicationContextProvder" class="com.mycompany.ApplicationContextProvider"/>

<!-- CACHE -->
<cache:annotation-driven cache-manager="springEhCacheManager"/>

<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="/WEB-INF/conf/ehcache.xml"/>
</bean>

<bean id="springEhCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <constructor-arg ref="ehCacheManager"/>
</bean>

<bean id="cacheProvider" class="org.springmodules.cache.provider.ehcache.EhCacheFacade">
    <property name="cacheManager" ref="ehCacheManager"/>
</bean>

<bean id="cacheService" class="com.myapp.cache.DefaultEHCacheServiceImp">
    <constructor-arg index="0" ref="ehCacheManager"/>
</bean>

<!-- ALIVE -->
<bean id="voldemortAlive"
      class="com.myapp.voldemort.VoldemortAliveImp">
</bean>

<bean id="atlasAlive"
      class="com.myapp.atlas.AtlasAliveImp">
</bean>



<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>

<!-- custom beans defined -->

<bean id="updatersSynchronizedTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"/>
<bean id="updatersSynchronizedTaskExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false"/>

福课

package com.foo

@Service
public class Foo {

    @Autowired
    private Bar bar;

    ... lots of stuff here ...

    @PostConstruct
    protected void init() {
         ... method body ...
    }

... more logic ...

}

酒吧班

package com.bar

@Repository
public class Bar extends BarParent implements ApplicationListener<BarEvent>   {

... more stuff ...

    @Cacheable("cache_name")
    public List<Baz> cachedMethod(final Integer code) {
        ... some logic here ...
    }
...
}

给予的例外

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.bar.Bar com.foo.Foo.bar; nested exception is java.lang.IllegalArgumentException: Can not set com.bar.Bar field com.foo.Foo.bar to $Proxy86
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
... 63 more
Caused by: java.lang.IllegalArgumentException: Can not set com.bar.Bar field com.foo.Foo.bar to $Proxy86
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
at java.lang.reflect.Field.set(Field.java:657)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:513)
... 65 more

提前谢谢你。

共有1个答案

魏澄邈
2023-03-14

改变

<cache:annotation-driven cache-manager="springEhCacheManager"/>

<cache:annotation-driven cache-manager="springEhCacheManager" proxy-target-class="true"/>

由于其中一种方法是@Cacheable,Spring会为生成一个代理。由于默认代理生成策略基于Java动态代理,并且Bar实现接口ApplicationListener,因此生成的代理是ApplicationListener的子类型,而不是Bar。因此,当遇到@Autowired Bar时,Spring会尝试注入一个不是Bar子类型的代理实例,因此会出现错误。

通过将proxy target class设置为true,Spring将被迫使用CGLIB生成基于类的代理,@Autowired Bar将注入一个Bar实例。

 类似资料:
  • 尝试在这里使用Mapstruct做一些测试。我有以下类: 试验等级 测绘仪 在这里考虑模型 生成的通用MapperImpl: 当我尝试运行测试时,他给出了以下错误: MapperTest中的@Autowire不起作用。它声称:“无法自动连线。找不到“UsuarioMapper”类型的beans。 已尝试: gradle build(无错误) gradle build-x test(无错误) 使缓存

  • 问题内容: 几天来,我一直在尝试创建Spring CRUD应用程序。我糊涂了。我无法解决此错误。 还有这个 客户端控制器 ClientServiceImpl 客户资料库 我浏览了许多类似的问题,但是没有人回答不能帮助我。 问题答案: ClientRepository应该用标记注释。使用你当前的配置,Spring将不会扫描该类并对其有所了解。在启动和连接时,找不到ClientRepository类。

  • 当我从not bean类中的方法调用Cacheable方法时,我突然发现@Cacheable不起作用。 请在下面找到我的代码,并帮助我什么是问题或我错过的东西。

  • 问题内容: 我得到一个在服务启动(创建bean),当我使用Java 8层的功能。 Java 8已设置并且正在运行。该代码正确编译。服务启动时,由于未创建Bean,因此服务无法侦听端口。当我更改代码(删除Java 8构造)时,服务启动,并且一切正常。 这是我正在使用的代码(该服务启动的工作代码): 使用Java 8构造的相同代码: 包含这段代码的类的Bean是使用组件扫描创建的。 以下是使用第二个代

  • 我试图编译一个非常简单的程序,将包含3个用户的简单表保存到http://localhost/phpmyadmin,以清空名为,users ' '的数据库,但它仍然显示异常,您可以看到。 1个异常org.springframework.beans.factory。BeanCreationException:创建在类路径资源[org/springframework/boot/autoconfigure

  • 当我启动Weblogic时(使用jar:hibernate-core-4.3.6.final.jar和hibernate-jpa-2.1-api-1.0.0.final.jar),遇到以下错误信息: 无法自动连接字段:private org.hibernate.sessionFactory com.nscorp.lars.shopleveling.core.dao.impl.Dataloaddao