2011-12-31 14 views
52

通常のサーブレットについては、context listenerを宣言することができますが、Spring MVCの場合はSpringがこれを簡単にするでしょうか?アプリケーションコンテキストの初期化イベントにフックを追加するにはどうすればよいですか?

さらに、コンテキストリスナーを定義してから、servlet.xmlまたはapplicationContext.xmlに定義されたBeanにアクセスする必要がある場合、どのようにアクセスできますか?あなたのservlet.xmlapplicationContext.xmlファイル内でこの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(...) 
      // ... 
     } 
    } 
} 

:あなたは、このような何かをApplicationListenerインタフェースを実装するBeanを作成して登録する必要があり、それを行うために

答えて

82

Spring has some standard events which you can handle.

<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に対しても呼び出されます。 –

+0

注釈を使用して2つのクラスを宣言するとどうなりますか?非注釈(XML)と2つの?宣言された順番で発射されるのだろうか?ありがとう;) – momomo

+0

情報のためだけに、開始されたコンテキストのイベントはContextStartedEventです。 文書: - http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/context/event/ContextStartedEvent。 html –

58

春4.2ので、あなたが@EventListenerdocumentation

@Component 
class MyClassWithEventListeners { 

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

プロパティをどのように出力するのですか?このメソッドはパラメータを受け取りません。 –

1

を使用することができ、私は(それはHashMapを作成していたURLを入力することで、単一ページのアプリケーションを持っていました私のウェブページで使用されていました)。私は物事を以下でした 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-作成し、時間

1- web.xmlにエントリの下に追加されました起動時にサーバーにすべてをロードするために私のコントローラクラスで

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

、3- ServletContext内のマップを最初にチェックするコードを更新するコードを更新しました

@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クラスで使用され、すでに実装されているservletContextから結果を取得します。

1

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

@Component注釈またはXMLでこのクラスを登録し、そのいずれかの方法のWANどこアノテーションを使用したクラス

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) { 
      } 
     } 
    } 
} 

を作成

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

あなたの注釈を作成します。コンテキストを初期化した後に実行する場合は、

@AfterSpringLoadComplete 
    public void init() {} 
関連する問題