我注意到我的bean 在jar的spring-boot应用程序上一次调用了@PostConstruct
,init()
并且@Scheduled
两次。这是初始化两次的示例bean。
@Component
@ConfigurationProperties(prefix = "task")
public class CancelTask {
private static Logger log = LoggerFactory.getLogger(CancelTask.class);
@PostConstruct
public void init() {
log.info("CancelTask init:{}", this);
printStackTrace();
}
private void printStackTrace() {
StackTraceElement[] stackElements = new Throwable().getStackTrace();
StringBuilder sb = new StringBuilder();
if (stackElements != null) {
for (int i = 0; i < stackElements.length; i++) {
sb.append("" + stackElements[i] + "\n");
}
}
log.info(sb.toString());
}
@Scheduled(cron = "0 */1 * * * ?")
public void closeTask() {
log.info("close task start....{}", this);
printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
@PostConstruct
而@Scheduled
被称为两次:
从日志开始,PostConstruct首先被调用:
[INFO] [2017-12-20 19:54:29,872] [c.n.m.workbench.daemon.task.CancelTask]: CancelTask init:com.netease.mail.workbench.daemon.task.CancelTask@34451ed8
[INFO] [2017-12-20 19:54:29,873] [c.n.m.workbench.daemon.task.CancelTask]: com.netease.mail.workbench.daemon.task.CancelTask.printStackTrace(CancelTask.java:85)
com.netease.mail.workbench.daemon.task.CancelTask.init(CancelTask.java:81)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134)
com.netease.mail.workbench.Application.main(Application.java:61)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
Run Code Online (Sandbox Code Playgroud)
第二个叫做:
[INFO] [2017-12-20 19:54:36,148] [c.n.m.workbench.daemon.task.CancelTask]: CancelTask init:com.netease.mail.workbench.daemon.task.CancelTask@34451ed8
[INFO] [2017-12-20 19:54:36,150] [c.n.m.workbench.daemon.task.CancelTask]: com.netease.mail.workbench.daemon.task.CancelTask.printStackTrace(CancelTask.java:85)
com.netease.mail.workbench.daemon.task.CancelTask.init(CancelTask.java:81)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311)
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:400)
org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.rebind(ConfigurationPropertiesRebinder.java:107)
org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.rebind(ConfigurationPropertiesRebinder.java:90)
org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.onApplicationEvent(ConfigurationPropertiesRebinder.java:138)
org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.onApplicationEvent(ConfigurationPropertiesRebinder.java:51)
org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration.afterSingletonsInstantiated(ConfigurationPropertiesRebinderAutoConfiguration.java:79)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:781)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134)
com.netease.mail.workbench.Application.main(Application.java:61)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
Run Code Online (Sandbox Code Playgroud)
和@Scheduled被称为两次一次:
[INFO] [2017-12-20 19:57:00,006] [c.n.m.workbench.daemon.task.CancelTask]: close task start....com.netease.mail.workbench.daemon.task.CancelTask@34451ed8
[INFO] [2017-12-20 19:57:00,006] [c.n.m.workbench.daemon.task.CancelTask]: close task start....com.netease.mail.workbench.daemon.task.CancelTask@34451ed8
Run Code Online (Sandbox Code Playgroud)
当我删除@ConfigurationProperties
,@PostConstruct
并且@Scheduled
被称为只有一次。而且我非常确定CancelTask
该类只有一个实例。
(有些意见表明)这是不相关的春云所有的,因为我可以重现此问题没有它。
发生这种情况是因为您正在为创建两个bean CancelTask
。一个是由@Component
(+扫描的@ComponentScan
)创建的,另一个是由于@ConfigurationProperties
(+启用的@EnableConfigurationProperties(CancelTask.class)
)创建的。
如果我在本地运行相同的示例,则会得到不同的实例ID:
com.example.demo.CancelTask: CancelTask init:com.example.demo.SomethingProperties@273f65d9
com.example.demo.CancelTask: CancelTask init:com.example.demo.SomethingProperties@6066ff52
Run Code Online (Sandbox Code Playgroud)
您不应该在单个Spring组件中混合应用程序功能和配置基础结构。您应该将此组件切成两半;经验法则:如果您不能命名您的配置属性类SomethingProperties
,那么它的作用可能超出了预期。
由于配置属性是bean,因此可以将其注入任何其他组件中。
归档时间: |
|
查看次数: |
1496 次 |
最近记录: |