2011-12-31 24 views

回答

82

Spring has some standard events which you can handle.

要做到这一点,你必须创建并注册一个实现ApplicationListener接口的bean,这样的事情:

package test.pack.age; 

import org.springframework.context.ApplicationContext; 
import org.springframework.context.ApplicationEvent; 
import org.springframework.context.ApplicationListener; 
import org.springframework.context.event.ContextRefreshedEvent; 

public class ApplicationListenerBean implements ApplicationListener { 

    @Override 
    public void onApplicationEvent(ApplicationEvent event) { 
     if (event instanceof ContextRefreshedEvent) { 
      ApplicationContext applicationContext = ((ContextRefreshedEvent) event).getApplicationContext(); 
      // now you can do applicationContext.getBean(...) 
      // ... 
     } 
    } 
} 

你那么你servlet.xmlapplicationContext.xml文件里注册这个bean:

<bean id="eventListenerBean" class="test.pack.age.ApplicationListenerBean" /> 

当初始化应用上下文时,Spring会通知它。

在Spring 3(如果您使用的是此版本),ApplicationListener class is generic,您可以声明您感兴趣的事件类型,并且相应地过滤该事件。您可以简化一点你的bean这样的代码:

public class ApplicationListenerBean implements ApplicationListener<ContextRefreshedEvent> { 

    @Override 
    public void onApplicationEvent(ContextRefreshedEvent event) { 
     ApplicationContext applicationContext = event.getApplicationContext(); 
     // now you can do applicationContext.getBean(...) 
     // ... 
    } 
} 
+0

好的,谢谢。很高兴知道spring3过滤事件。我之前注意到applicationlistener类。但它的钩子也将被调用RequestHandledEvent。 – 2012-01-11 00:16:07

+0

任何想法如果你使用注释的东西会发生什么,并且你声明了两个类?非注释(XML)和两个?他们会按照宣布的顺序开火吗?谢谢;) – momomo 2012-06-12 14:28:45

+0

仅供参考,事件的上下文开始是ContextStartedEvent 文档: - http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/context/event/ContextStartedEvent。 html – 2013-09-12 10:51:08

58

从Spring 4.2可以使用@EventListenerdocumentation

@Component 
class MyClassWithEventListeners { 

    @EventListener({ContextRefreshedEvent.class}) 
    void contextRefreshedEvent() { 
     System.out.println("a context refreshed event happened"); 
    } 
} 
+0

如何打印属性等,这种方法似乎没有参数? – 2018-03-02 16:20:11

1

我对输入URL它创建一个HashMap的一个单页的应用程序(由我的网页使用),其中包含来自多个数据库的数据。 我下面的东西到服务器的过程中启动加载一切时间

1-创建ContextListenerClass

public class MyAppContextListener implements ServletContextListener 
    @Autowired 

    private MyDataProviderBean myDataProviderBean; 

    public MyDataProviderBean getMyDataProviderBean() { 

    return MyDataProviderBean; 

     } 

     public void setMyDataProviderBean(

     MyDataProviderBean MyDataProviderBean) { 

    this.myDataProviderBean = MyDataProviderBean; 

     } 

     @Override 

     public void contextDestroyed(ServletContextEvent arg0) { 

     System.out.println("ServletContextListener destroyed"); 

     } 


     @Override 

     public void contextInitialized(ServletContextEvent context) { 


    System.out.println("ServletContextListener started"); 

    ServletContext sc = context.getServletContext(); 

    WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(sc); 

    MyDataProviderBean MyDataProviderBean = (MyDataProviderBean)springContext.getBean("myDataProviderBean"); 

    Map<String, Object> myDataMap = MyDataProviderBean.getDataMap(); 

    sc.setAttribute("myMap", myDataMap); 

    } 

2-新增条目下方在web.xml

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
<listener> 
    <listener-class>com.context.listener.MyAppContextListener</listener-class> 
</listener> 

3-在我的控制器类更新代码首先检查servlet中的地图文本

@RequestMapping(value = "/index", method = RequestMethod.GET) 
     public String index(@ModelAttribute("model") ModelMap model) { 

      Map<String, Object> myDataMap = new HashMap<String, Object>(); 
      if (context != null && context.getAttribute("myMap")!=null) 
      { 

       myDataMap=(Map<String, Object>)context.getAttribute("myMap"); 
      } 

      else 
      { 

       myDataMap = myDataProviderBean.getDataMap(); 
      } 

      for (String key : myDataMap.keySet()) 
      { 
       model.addAttribute(key, myDataMap.get(key)); 
      } 
      return "myWebPage"; 

     } 

当我启动tomcat时,发生了很多变化,它会在startTime期间加载dataMap,并将所有内容放入servletContext中,然后由Controller Class使用它从已填充的servletContext中获取结果。

1

通过@Component注解或XML

<bean class="ua.adeptius.PostProxyInvokerContextListener"/> 

创建注释

@Retention(RetentionPolicy.RUNTIME) 
    public @interface AfterSpringLoadComplete { 
    } 

创建类

public class PostProxyInvokerContextListener implements ApplicationListener<ContextRefreshedEvent> { 

    @Autowired 
    ConfigurableListableBeanFactory factory; 

    @Override 
    public void onApplicationEvent(ContextRefreshedEvent event) { 
     ApplicationContext context = event.getApplicationContext(); 
     String[] names = context.getBeanDefinitionNames(); 
     for (String name : names) { 
      try { 
       BeanDefinition definition = factory.getBeanDefinition(name); 
       String originalClassName = definition.getBeanClassName(); 
       Class<?> originalClass = Class.forName(originalClassName); 
       Method[] methods = originalClass.getMethods(); 
       for (Method method : methods) { 
        if (method.isAnnotationPresent(AfterSpringLoadComplete.class)){ 
         Object bean = context.getBean(name); 
         Method currentMethod = bean.getClass().getMethod(method.getName(), method.getParameterTypes()); 
         currentMethod.invoke(bean); 
        } 
       } 
      } catch (Exception ignored) { 
      } 
     } 
    } 
} 

注册此类,并在那里你婉任何方法使用注解你想在上下文初始化后运行,如:

@AfterSpringLoadComplete 
    public void init() {} 
相关问题