当应用程序第一次启动时,是否有任何Spring 3功能可以执行某些方法?我知道我可以设置一个带@Scheduled
注释的方法,它只是在启动后执行,但它会定期执行.
ska*_*man 182
如果通过"应用程序启动"你的意思是"应用程序上下文启动",那么是的,有很多方法可以做到这一点,最简单的(对于单例bean,无论如何)是用你的方法注释@PostConstruct
.看一下链接以查看其他选项,但总的来说它们是:
@PostConstruct
afterPropertiesSet()
由InitializingBean
回调接口定义从技术上讲,这些是bean生命周期的钩子,而不是上下文生命周期,但在99%的情况下,这两者是等价的.
如果你需要专门挂钩上下文启动/关闭,那么你可以实现Lifecycle
接口,但这可能是不必要的.
Ste*_*erl 102
这很容易用ApplicationListener
.听听Spring的说法,我听到了这个ContextRefreshedEvent
:
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@Component
public class StartupHousekeeper implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(final ContextRefreshedEvent event) {
// do whatever you need here
}
}
Run Code Online (Sandbox Code Playgroud)
应用程序侦听器在Spring中同步运行.如果您想确保只执行一次代码,只需在组件中保留一些状态即可.
UPDATE
从Spring 4.2+开始,你也可以使用@EventListener
注释来观察ContextRefreshedEvent
(感谢@bphilipnyc指出这一点):
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@Component
public class StartupHousekeeper {
@EventListener(ContextRefreshedEvent.class)
public void contextRefreshedEvent() {
// do whatever you need here
}
}
Run Code Online (Sandbox Code Playgroud)
vph*_*nyc 36
在Spring 4.2+中,你现在可以简单地做到:
@Component
class StartupHousekeeper {
@EventListener(ContextRefreshedEvent.class)
void contextRefreshedEvent() {
//do whatever
}
}
Run Code Online (Sandbox Code Playgroud)
Zom*_*ies 12
如果你使用弹簧靴,这是最好的答案.
我觉得@PostConstruct
和其他各种生命周期的插入是有关的方式.这些可能直接导致运行时问题或由于意外的bean /上下文生命周期事件而导致不明显的缺陷.为什么不直接使用普通Java调用bean?你仍然用'spring way'调用bean(例如:通过spring AoP代理).最重要的是,它是普通的java,不能比这更简单.不需要上下文侦听器或奇怪的调度程序.
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext app = SpringApplication.run(DemoApplication.class, args);
MyBean myBean = (MyBean)app.getBean("myBean");
myBean.invokeMyEntryPoint();
}
}
Run Code Online (Sandbox Code Playgroud)
对于在尝试引用@PostConstruct注释时收到警告的Java 1.8用户,我最终捎带了@Scheduled注释,如果你已经有一个带有fixedRate或fixedDelay的@Scheduled作业,你可以这样做.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@EnableScheduling
@Component
public class ScheduledTasks {
private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasks.class);
private static boolean needToRunStartupMethod = true;
@Scheduled(fixedRate = 3600000)
public void keepAlive() {
//log "alive" every hour for sanity checks
LOGGER.debug("alive");
if (needToRunStartupMethod) {
runOnceOnlyOnStartup();
needToRunStartupMethod = false;
}
}
public void runOnceOnlyOnStartup() {
LOGGER.debug("running startup job");
}
}
Run Code Online (Sandbox Code Playgroud)
我们所做的是org.springframework.web.context.ContextLoaderListener
在上下文开始时扩展到打印内容.
public class ContextLoaderListener extends org.springframework.web.context.ContextLoaderListener
{
private static final Logger logger = LoggerFactory.getLogger( ContextLoaderListener.class );
public ContextLoaderListener()
{
logger.info( "Starting application..." );
}
}
Run Code Online (Sandbox Code Playgroud)
然后配置子类web.xml
:
<listener>
<listener-class>
com.mycomp.myapp.web.context.ContextLoaderListener
</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
小智 6
使用SpringBoot,我们可以在启动时通过@EventListener
注释执行方法
@Component
public class LoadDataOnStartUp
{
@EventListener(ApplicationReadyEvent.class)
public void loadData()
{
// do something
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
215776 次 |
最近记录: |