如果一个bean被延迟加载,那么在懒惰加载的bean中定义的所有bean都会被延迟加载吗? (即使他们没有定义@Lazy)
我有这些豆子:
@Service
@ConditionalOnProperty(
name = {"publish.feed.events"},
havingValue = "true"
)
public class EventPublishService {
@Autowired
private KafkaPublisher kafkaPublisher;
}
////////////////////
@Service
public class EventService {
@Autowired
@Lazy
private EventPublishService eventPublishService;
@Value("${publish.feed.events:false}")
private boolean isPublishEvents;
}
/////////////////////////
@Component
public class KafkaPublisher {
@Value("${kafka.producer.financial_feed.topic}")
private String financeFeedTopic;
}
任何我的application.properties只有一个属性
publish.feed.events=false
因为,我没有加载EventPublishService bean(因为属性为false),我希望不应该加载依赖bean KafkaPublisher。但是,我在启动时收到错误,这意味着即使没有加载EventPublishService bean,KafkaPublisher bean也会被加载。
如何确保不应加载KafkaPublisher bean? 因此,对于不需要EventPublishService bean的人来说,属性不应该是必需的吗?
org.springframework.beans.factory.BeanCreationException:错误 用名称' kafkaPublisher创建bean&#39 ;:注入自动装配 依赖失败;嵌套异常是 java.lang.IllegalArgumentException:无法解析占位符 ' kafka.producer.financial_feed.topic'价值 " $ {kafka.producer.financial_feed.topic}" at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:379) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1344) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:578) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.AbstractBeanFactory.lambda $ doGetBean $ 0(AbstractBeanFactory.java:317) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) 〜[弹簧上下文5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) 〜[弹簧上下文5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [弹簧引导2.0.1.RELEASE.jar:2.0.1.RELEASE] 在org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [弹簧引导2.0.1.RELEASE.jar:2.0.1.RELEASE] 在org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [弹簧引导2.0.1.RELEASE.jar:2.0.1.RELEASE] 在org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [弹簧引导2.0.1.RELEASE.jar:2.0.1.RELEASE] 在org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [弹簧引导2.0.1.RELEASE.jar:2.0.1.RELEASE] 在com.example.demo.DemoApplication.main(DemoApplication.java:17) [main /:na]引起:java.lang.IllegalArgumentException:不能 解决占位符' kafka.producer.financial_feed.topic'价值 " $ {kafka.producer.financial_feed.topic}" 在org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:172) 〜[弹簧芯5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124) 〜[弹簧芯5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:237) 〜[弹簧芯5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:211) 〜[弹簧芯5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda $ processProperties $ 0(PropertySourcesPlaceholderConfigurer.java:175) 〜[弹簧上下文5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:839) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1086) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1065) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:584) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] 在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:373) 〜[弹簧豆-5.0.5.RELEASE.jar:5.0.5.RELEASE] ...省略了16个常见帧
答案 0 :(得分:11)
创建容器时创建单例范围并设置为预先实例化(默认值)的Bean
因此,如果将@Lazy
放在@Autowired
上并不重要,只要bean本身没有定义为懒惰,就会在启动时创建bean :
@Component
public class KafkaPublisher {
...
}
如果您想要懒惰地初始化此bean,请将 @Lazy
放在其上。如果你想让bean注入过程变得懒惰,那就把@Lazy
放在@Autowired
上,就这么简单。
通过在@Configuration
类中声明它们并标记配置@Lazy
,可以实现Lazily初始化一组相关bean。但是,请注意,只要初始化@Configuration
类,就会初始化所有声明的bean。
@Lazy
@Configuration
@ComponentScan(...) // will be lazily initialized with config
public class LazyConfiguration {
@Bean
public SomeBean beanName() { // will be lazily initialized with config
return new SomeBean();
}
@Bean
public OtherBean beanName() { // will be lazily initialized with config
return new OtherBean();
}
}
但是,在使用@ComponentScan
时,请确保您想要懒惰地初始化的bean(其中@Service
,@Component
等)尚未被其他某些上下文扫描。如果是,请将它们作为排除项添加到扫描该上下文中。
以下过时的答案,出于历史目的(在OP完全改变问题之前):
在bean中声明bean不被认为是一种好习惯,但是如果你将@Configuration
标记为懒惰,那么它内部的所有bean都会被懒惰地初始化,如@Lazy
中所述' javadoc:
如果@Configuration类中存在Lazy,则表示全部 @Configuration中的@Bean方法应该被懒惰地初始化。
如果"在#34; 中定义的bean实际上意味着注入点,例如@Autowired
,javadoc也有答案:
懒惰注释也可以放在标有的注入点上 自动装配或注入:在这种情况下,它会导致创建一个 作为替代方案,所有受影响的依赖项的延迟解析代理 使用ObjectFactory或Provider。
但是,实际的autowired bean将被急切地初始化(如果没有标记为@Lazy)。在这种情况下注射本身就是懒惰的。
否则,请澄清你的意思。