[英]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应用程序,那么您可能同时拥有
ContextLoaderListener
和DispatcherServlet
,它们都将创建自己的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.