In the following configuration bean example,
@Configuration
public class LazyConfig
{
@Bean
@Lazy
public SomeBean someBean(final DependencyBean dependencyBean)
{
return new SomeBean(dependencyBean);
}
}
I expected the following test using ApplicationContextRunner
should be working, but it fails:
class LazyConfigTest
{
ApplicationContextRunner runner = new ApplicationContextRunner()
.withUserConfiguration(LazyConfig.class);
@Test
void testNoLazyIsLoaded()
{
runner.run(context -> {
.assertj.core.api.Assertions.assertThat(context).getBeanNames(SomeBean.class).isEmpty();
// > Expecting empty but was: ["someBean"]
.assertj.core.api.Assertions.assertThat(context).doesNotHaveBean(SomeBean.class);
// > Expecting not to have, but found: <["someBean"]>
});
}
}
But then trying to get the bean itself fails for depedant,
context.getBean(SomeBean.class);
// > Error creating bean with name 'someBean' defined in .lucasvc.lazy.config.LazyConfig: Unsatisfied dependency expressed through method 'someBean' parameter 0: No qualifying bean of type '.lucasvc.lazy.DependencyBean' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
It is expected that there is such "beans" in the context, even annotated method with Lazy
?
How should be the best way to test the Lazy
behavior?
In the following configuration bean example,
@Configuration
public class LazyConfig
{
@Bean
@Lazy
public SomeBean someBean(final DependencyBean dependencyBean)
{
return new SomeBean(dependencyBean);
}
}
I expected the following test using ApplicationContextRunner
should be working, but it fails:
class LazyConfigTest
{
ApplicationContextRunner runner = new ApplicationContextRunner()
.withUserConfiguration(LazyConfig.class);
@Test
void testNoLazyIsLoaded()
{
runner.run(context -> {
.assertj.core.api.Assertions.assertThat(context).getBeanNames(SomeBean.class).isEmpty();
// > Expecting empty but was: ["someBean"]
.assertj.core.api.Assertions.assertThat(context).doesNotHaveBean(SomeBean.class);
// > Expecting not to have, but found: <["someBean"]>
});
}
}
But then trying to get the bean itself fails for depedant,
context.getBean(SomeBean.class);
// > Error creating bean with name 'someBean' defined in .lucasvc.lazy.config.LazyConfig: Unsatisfied dependency expressed through method 'someBean' parameter 0: No qualifying bean of type '.lucasvc.lazy.DependencyBean' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
It is expected that there is such "beans" in the context, even annotated method with Lazy
?
How should be the best way to test the Lazy
behavior?
1 Answer
Reset to default 1You have to consider how @Lazy
beans work in Spring. If I have a class LazyBeanA that is marked as @Lazy
, and I declare a class NotLazyB that autowires LazyBeanA does that negate LazyBeanA's laziness? No, it doesn't. But how does it construct NotLazyB if it's "eager" if not all properties can be satisfied? It can't satisfy the LazyBeanA autowire because it's lazy. Well, Spring gets around that by instantiating a proxy that sits in front of LazyBeanA. LazyBeanA isn't constructed, but the Proxy is. The proxy is a "stunt" bean. It's stands in for LazyBeanA until you invoke a method on it. At that point it constructs LazyBeanA, populates it's dependencies, and invokes the method.
So there is something registered under that bean's class/id. It's just the stunt bean.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744195091a4562618.html
@Lazy
so your bean will be there but it will be a proxy which will be used instead of your actual bean (which will be deferred until there is some action on it). Which is what you see when you try to get the bean as the dependent bean isn't there and thus it fails to actually construct it. – M. Deinum Commented Mar 25 at 12:58