在Spring中启动时执行方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Spring中启动时执行方法相关的知识,希望对你有一定的参考价值。

当应用程序第一次启动时,是否有任何Spring 3功能可以执行某些方法?我知道我可以使用@Scheduled注释设置方法,并在启动后立即执行,但随后会定期执行。

答案

如果通过“应用程序启动”你的意思是“应用程序上下文启动”,那么是的,有many ways to do this,最简单的(对于单身豆,无论如何)是用@PostConstruct注释你的方法。看一下链接以查看其他选项,但总的来说它们是:

  • @PostConstruct注释的方法
  • afterPropertiesSet()InitializingBean回调接口定义
  • 自定义配置的init()方法

从技术上讲,这些是bean生命周期的钩子,而不是上下文生命周期,但在99%的情况下,这两者是等价的。

如果你需要专门挂钩上下文启动/关闭,那么你可以改为implement the Lifecycle interface,但这可能是不必要的。

另一答案
Initialize default Locale and Timezone with Spring configuration
另一答案

如果要在应用程序完全运行之前配置bean,可以使用AppStartListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent event) { if(event instanceof ApplicationReadyEvent){ System.out.print("ciao"); } } }

@Autowired
另一答案

您可以在组件上使用@Autowired private void configureBean(MyBean: bean) { bean.setConfiguration(myConfiguration); } ,这将在服务器启动并初始化所有bean后调用。

@EventListener
另一答案

对于位于包@EventListener public void onApplicationEvent(ContextClosedEvent event) { } 的文件StartupHousekeeper.java

com.app.startup这样做:

StartupHousekeeper.java

并在@Component public class StartupHousekeeper { @EventListener(ContextRefreshedEvent.class) public void keepHouse() { System.out.println("This prints at startup."); } } 这样做:

myDispatcher-servlet.java
另一答案

这很容易用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 
  }
}

应用程序侦听器在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 
  }
}
另一答案

在Spring 4.2+中,你现在可以简单地做到:

@Component
class StartupHousekeeper {

    @EventListener(ContextRefreshedEvent.class)
    void contextRefreshedEvent() {
        //do whatever
    }
}
另一答案

如果你使用弹簧靴,这是最好的答案。

我觉得@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();
    }
}
另一答案

对于在尝试引用@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");
    }

}
另一答案

我们所做的是扩展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..." );
    }
}

然后在web.xml中配置子类:

<listener>
    <listener-class>
        com.mycomp.myapp.web.context.ContextLoaderListener
    </listener-class>
</listener>
另一答案

使用Spring Boot,我们可以通过qazxsw poi annotation在启动时执行一个方法

@EventListener
另一答案

请注意,仅在您的@Component public class LoadDataOnStartUp { @EventListener(ApplicationReadyEvent.class) public void loadData() { // do something } } 方法依赖于完全初始化的弹簧上下文时才建议这样做。例如:你想用事务划分来调用dao

您还可以使用fixedDelay设置得非常高的预定方法

runOnceOnStartup

这有利于整个应用程序连线(Transactions,Dao,...)

@Scheduled(fixedDelay = Long.MAX_VALUE) public void runOnceOnStartup() { dosomething(); } 看到

另一答案

发布另一个实现WebApplicationInitializer的解决方案,在实例化任何spring bean之前调用很多,以防有人拥有该用例

Scheduling tasks to run once, using the Spring task namespace

以上是关于在Spring中启动时执行方法的主要内容,如果未能解决你的问题,请参考以下文章

一张图,理顺 Spring Boot应用在启动阶段执行代码的几种方式

一张图,理顺 Spring Boot应用在启动阶段执行代码的几种方式

在Spring中启动时执行方法

Spring Boot 启动时自动执行代码的几种方式。。

片段中的Android按钮单击方法(崩溃)

Spring Boot 启动时,让方法自动执行的 4 种方法!