2 回答
TA贡献1811条经验 获得超5个赞
好的,谢谢大家的帮助。无意沮丧,发布配置和流程对我的想法没有帮助,因为我在下面发现了:
仔细检查有一个例外:
org.springframework.expression.AccessException: Could not resolve bean reference against BeanFactory
有问题的参考是对我使用 @SpyBean 的实用程序中的一个方法:
<int:transformer
expression="@utilities.asMap('licence_id', headers[licenceId], 'message', 'Delivered: ' + headers[confirmedMessage], 'secured_session_id', headers[visitorSession].getSecureSessionId())" />
它不是一个单独的 ApplicationContext 而是 SpEL 不会接受间谍 bean,因为引用已更改或类似。
所以,我不理会这些实用程序,而是改造了它内部的另一个 bean 来生成数字,并在其上使用了 SpyBean。现在 Spring Integration/SpEL 再次感到高兴,因为它使用的实用程序 bean 是正确的,并且模拟发生在该 bean 内部并且对 SpEL 透明。
@Component
public class RandomSupplier implements Supplier<Double> {
@Override
public Double get() {
return Math.random();
}
}
public class FullIntegrationTest {
@Autowired
private MockMvc mvc;
@SpyBean
private RandomSupplier randomSupplier;
@Autowired // This is only necessary for the toy test below
private Utilities utilities;
@BeforeEach
public void setupAfterInit() {
Mockito.when(randomSupplier.get()).thenReturn(0.5);
}
@Test
public void t0() throws IOException {
System.out.println(utilities.getRandom());
}
...
现在 Spring Integration/SpEL 再次感到高兴,因为它工作的实用程序 bean 是正确的,并且模拟发生在该 bean 内部。
三个教训:不要窥探 Spring Integration Flow 中 SpEL 中直接引用的 bean;阅读日志;你永远不可能有足够的间接性:)
TA贡献1864条经验 获得超6个赞
我试图用最少的配置重现你的问题:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {Ctx.class})
public class XTest {
@SpyBean
private Random random1;
@Autowired private Supplier<Integer> intSupplier;
@Test
public void test() {
Mockito.when(random1.nextInt()).thenReturn(Integer.MAX_VALUE);
int i = intSupplier.get();
System.out.println("i=" + i);
}
@Configuration
public static class Ctx {
@Bean
static Random random1() {
return ThreadLocalRandom.current();
}
@Bean
static Supplier<Integer> intSupplier(Random random1) {
return random1::nextInt;
}
}
}
正如预期的那样打印
i=2147483647
所以,你的运行时配置一定有问题......你能分享一下吗?我猜 spring-integration 正在使用另一个 ApplicationContext。我知道这不是答案,如果没有帮助,我会删除它。
添加回答
举报