我的Spring 4应用程序使用Reactor 2,无法启动:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'orderHandlerConsumer' could not be injected as a 'fm.data.repository.OrderHandlerConsumer' because it is a JDK dynamic proxy that implements:
reactor.fn.Consumer
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.
OrderHandlerConsumer
非常简单:
@Service
@Order(Ordered.HIGHEST_PRECEDENCE)
public class OrderHandlerConsumer implements Consumer<Event<OrderEnvelope>> {
@Override
public void accept(Event<OrderEnvelope> event) {
event.getData().getLatch().countDown();
}
}
有什么想法可能出了差错吗?
5条答案
按热度按时间kqqjbcuj1#
在您的application class文件中,将其定义为Spring application,在它下面添加。
bqjvbblv2#
虽然另一个答案可以解决这个问题,但我认为更适合我来解释为什么应用
proxyTargetClass = true
可以解决这个问题。首先,Spring作为一个框架,利用 * 代理 * 来为bean提供一些扩展功能,例如通过
@Transactional
的声明性事务,或者通过@Cacheable
的方式进行缓存等。一般来说,有两种方法(*)Spring可以在bean之上创建代理:Official documentation如果你感兴趣的话。
如果bean的原始类实现了至少一个接口,Spring可以创建bean的JDK动态代理(当然,如果这个bean需要代理)。所以Spring基本上是在运行时创建这个接口的另一个实现,在原始类的顶部添加一些额外的逻辑。
问题出在哪里:如果bean是通过JDK动态代理的方式进行代理,那么就无法通过bean的原类注入该bean。就像这样:
不会有用的。为什么?好吧,因为
@Transactional
告诉Spring它需要在运行时创建SomeService
的代理,并且在@EnableTransactionManagement
中我特别要求Spring通过JDK动态代理的方式来实现它- Spring会成功,因为JDK动态代理可以创建,但问题是在运行时没有SomeService
类型的bean,只有一个SomeInterface
类型的bean(顺便说一下,如果你不是通过类注入服务,而是通过接口注入服务,它会工作的,我假设你通过阅读上面的解释理解了原因)。**解决方案:**通过应用
@EnableTransactionManagement(proxyTargetClass = true)
(注意这里的 true 值),您可以强制spring创建CGLIB代理(此规则仅适用于使用声明式事务管理的bean,即经由注解)。在CGLIB代理的情况下,Spring将尝试扩展原始类,并在运行时在生成的子类中添加额外的功能。在这种情况下,按类注入将起作用-因为bean扩展了类SomeService
,所以会非常好用但是,一般来说,如果可能的话,按接口注入bean,而不是按类注入。在这种情况下,CGLIB和JDK动态代理都可以工作。因此,要注意spring可以使用的代理机制。希望有帮助,祝你今天愉快。
a8jjtwal3#
你可以给你的OrderHandlerConsumer类分配一个bean名,这样自动连接解析就更容易了。此外,不要用具体的类自动连接,试着用接口自动连接。以便您可以将@Service注解更改为,
并尝试使用接口类型进行自动连接,
wz3gfoph4#
请尝试如下自动装配
l7wslrjt5#
如果要代理的目标对象实现了至少一个接口,则将使用JDK动态代理。目标类型实现的所有接口都将被代理。如果目标对象没有实现任何接口,那么将创建一个CGLIB代理。
https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch08s06.html
你可以用两种方式称呼它
Spring AOP将为
OrderHandlerConsumer
创建一个示例。ScopedProxyMode.TARGET_CLASS
。然后你可以自动连接一个没有接口的示例[基于类]。*和Autowire的类如下。