简体   繁体   English

在spring-mvc应用程序的开头运行一个类

[英]running a class at the starting of spring-mvc application

is it possible to run a class at the time of application starting in spring mvc i want to initialize a thread in that class ?? 是否有可能在Spring MVC中启动应用程序时运行一个类,我想在该类中初始化一个线程?

or is there any way..? 还是有什么办法..?

                public class MyServletContextListener implements Runnable {



            public void run() {

                while (true) {

                try {
                    System.out.println("Inside run()");
                    Thread.sleep(10000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                }


            }

            }

this output i got after adding ApplicationListener interface 我在添加ApplicationListener接口后得到的输出

            NFO: HHH000206: hibernate.properties not found
            Jul 24, 2017 8:42:33 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
            INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
            Jul 24, 2017 8:42:35 PM org.hibernate.dialect.Dialect <init>
            INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
            Jul 24, 2017 8:42:36 PM org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl useContextualLobCreation
            INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4

            Thread Started
            getApplicationName() : /Hibernate_webservice
            getId() : org.springframework.web.context.WebApplicationContext:/Hibernate_webservice
            getParent() : null
            getDisplayName() : Root WebApplicationContext


            Jul 24, 2017 8:42:38 PM org.springframework.web.context.ContextLoader initWebApplicationContext
            INFO: Root WebApplicationContext: initialization completed in 8880 ms
            Jul 24, 2017 8:42:38 PM org.apache.catalina.core.ApplicationContext log
            INFO: Initializing Spring FrameworkServlet 'appServlet'
            Jul 24, 2017 8:42:38 PM org.springframework.web.servlet.DispatcherServlet initServletBean
            INFO: FrameworkServlet 'appServlet': initialization started
            Jul 24, 2017 8:42:38 PM org.springframework.web.context.support.XmlWebApplicationContext prepareRefresh
            INFO: Refreshing WebApplicationContext for namespace 'appServlet-servlet': startup date [Mon Jul 24 20:42:38 IST 2017]; parent: Root WebApplicationContext
            Jul 24, 2017 8:42:38 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
            INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/spring-config.xml]
            Jul 24, 2017 8:42:38 PM org.springframework.context.support.PropertySourcesPlaceholderConfigurer loadProperties
            INFO: Loading properties file from class path resource [application.properties]
            Jul 24, 2017 8:42:38 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
            INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
            Jul 24, 2017 8:42:38 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping registerHandlerMethod
            INFO: Mapped "{[/form],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView sample.test.TestController.method()
            Jul 24, 2017 8:42:39 PM org.hibernate.dialect.Dialect <init>
            INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
            Jul 24, 2017 8:42:39 PM org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl useContextualLobCreation
            INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4

            Thread Started
            getApplicationName() : /Hibernate_webservice
            getId() : org.springframework.web.context.WebApplicationContext:/Hibernate_webservice/appServlet
            getParent() : Root WebApplicationContext: startup date [Mon Jul 24 20:42:30 IST 2017]; root of context hierarchy
            getDisplayName() : WebApplicationContext for namespace 'appServlet-servlet'



            Thread Started
            getApplicationName() : /Hibernate_webservice
            getId() : org.springframework.web.context.WebApplicationContext:/Hibernate_webservice/appServlet
            getParent() : Root WebApplicationContext: startup date [Mon Jul 24 20:42:30 IST 2017]; root of context hierarchy
            getDisplayName() : WebApplicationContext for namespace 'appServlet-servlet'


            Jul 24, 2017 8:42:39 PM org.springframework.web.servlet.DispatcherServlet initServletBean
            INFO: FrameworkServlet 'appServlet': initialization completed in 1365 ms
            Jul 24, 2017 8:42:40 PM org.apache.coyote.AbstractProtocol start
            INFO: Starting ProtocolHandler ["http-nio-8082"]
            Jul 24, 2017 8:42:40 PM org.apache.coyote.AbstractProtocol start
            INFO: Starting ProtocolHandler ["ajp-nio-8011"]
            Jul 24, 2017 8:42:40 PM org.apache.catalina.startup.Catalina start
            INFO: Server startup in 19807 ms

Spring provides the ApplicationListener<ContextRefreshedEvent> interface and its onApplicationEvent(ContextRefreshedEvent event) hook. Spring提供了ApplicationListener<ContextRefreshedEvent> onApplicationEvent(ContextRefreshedEvent event) ApplicationListener<ContextRefreshedEvent>接口及其onApplicationEvent(ContextRefreshedEvent event)挂钩。

For example: 例如:

@Component
public class MyServiceCreationListener implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
      // do something on container startup
    }
}

Whatever you write in onApplicationEvent method will be executed once and only once when the Spring context is created. 无论您在onApplicationEvent方法中编写的内容是什么,在创建Spring上下文时将只执行一次。

If you find that this method is invoked more than once then you must have multiple ApplicationContext 's at play. 如果发现多次调用此方法,则必须同时运行多个ApplicationContext If you inspect event.getApplicationContext() you'll likely see that each of them have a different id and displayName and you may be able to work out their origins. 如果检查event.getApplicationContext()您可能会发现它们每个都有不同的id和displayName,并且您可能可以算出它们的来源。 If yours is a Spring MVC application then you may have both a ContextLoaderListener and DispatcherServlet , both of these create their own ApplicationContext each of which fires a ContextRefreshedEvent . 如果您的应用程序是Spring MVC应用程序,那么您可能同时拥有ContextLoaderListenerDispatcherServlet ,它们都将创建自己的ApplicationContext每个ApplicationContext都会触发ContextRefreshedEvent

If you want to determine which is the parent context you could try event.getApplicationContext().getParent() != null or you could toggle a class boolean within your ApplicationListener eg alreadyInitialised . 如果要确定哪个是父上下文,则可以尝试event.getApplicationContext().getParent() != null ,也可以在ApplicationListener中切换一个布尔类型,例如alreadyInitialised

There's also Spring 4's SmartInitializingSingleton which might allow you to hook into context creation at a different level. 还有Spring 4的SmartInitializingSingleton ,它可能使您可以进入不同级别的上下文创建。

您可以添加应用程序侦听器(一个类实现了上下文侦听器接口)来轻松创建线程。如果要创建时间表,则可以使用石英或弹簧计时器

As of Spring 4.2 you can simply use the @EventListener annotation, listening for ContextRefreshedEvent : 由于Spring 4.2的,你可以简单地使用@EventListener注解,听ContextRefreshedEvent

@Component
public class StartupManager {

    @EventListener(ContextRefreshedEvent.class)
    public void doStartupStuff() {
        // ... up, up and away
    }

}

Create a simple Java thread by extending Thread, and managed by Spring's container via @Component. 通过扩展Thread创建一个简单的Java线程,并通过@Component.通过Spring的容器进行管理@Component. The bean scope must be “prototype“, so that each request will return a new instance, to run each individual thread. bean范围必须是“原型”,以便每个请求将返回一个新实例,以运行每个单独的线程。

PrintThread.java:

package com.mkyong.thread;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrintThread extends Thread{

    @Override
    public void run() {

        System.out.println(getName() + " is running");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(getName() + " is running");
    }

}

AppConfig.java:

package com.mkyong.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages="com.mkyong.thread")
public class AppConfig{
}

App.java:

package com.mkyong;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.mkyong.config.AppConfig;
import com.mkyong.thread.PrintThread;

public class App
{
    public static void main( String[] args )
    {

        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

        PrintThread printThread1 = (PrintThread) ctx.getBean("printThread");
        printThread1.setName("Thread 1");

        PrintThread printThread2 = (PrintThread) ctx.getBean("printThread");
        printThread2.setName("Thread 2");

        PrintThread printThread3 = (PrintThread) ctx.getBean("printThread");
        printThread3.setName("Thread 3");

        PrintThread printThread4 = (PrintThread) ctx.getBean("printThread");
        printThread4.setName("Thread 4");

        PrintThread printThread5 = (PrintThread) ctx.getBean("printThread");
        printThread5.setName("Thread 5");

        printThread1.start();
        printThread2.start();
        printThread3.start();
        printThread4.start();
        printThread5.start();

    }
}

Output – The order will be vary each time, this is thread :) 输出–每次的顺序都会有所不同,这是线程:)

Thread 3 is running
Thread 2 is running
Thread 1 is running
Thread 5 is running
Thread 4 is running
Thread 2 is running
Thread 4 is running
Thread 5 is running
Thread 3 is running
Thread 1 is running

hope this is helpful :) 希望这会有所帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM