2011-12-31 6 views

risposta

82

Spring has some standard events which you can handle.

Per fare questo, è necessario creare e registrare un fagiolo che implementa l'interfaccia ApplicationListener, qualcosa di simile:

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(...) 
      // ... 
     } 
    } 
} 

È quindi registrare questo fagiolo all'interno del file servlet.xml o applicationContext.xml:

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

e Spring lo notificheranno quando il contesto dell'applicazione viene inizializzato.

Nella primavera 3 (se si utilizza questa versione), lo ApplicationListener class is generic ed è possibile dichiarare il tipo di evento a cui si è interessati e l'evento verrà filtrato di conseguenza. È possibile semplificare un po 'il codice di fagiolo in questo modo:

public class ApplicationListenerBean implements ApplicationListener<ContextRefreshedEvent> { 

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

ok, grazie.è bello sapere che spring3 filtra gli eventi. Ho notato la classe applicationlistener prima. ma i suoi hook verrebbero anche chiamati RequestHandledEvent. –

+0

Qualche idea su cosa succederà se usi le annotazioni e dichiari due classi? Non-annotazione (XML) e due? Spareranno nell'ordine dichiarato? grazie;) – momomo

+0

Solo per informazioni, l'evento per il contesto avviato è ContextStartedEvent Documenti: - http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/context/event/ContextStartedEvent. httml –

58

Dalla primavera 4.2 è possibile utilizzare @EventListener (documentation)

@Component 
class MyClassWithEventListeners { 

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

come faccio a stampare le proprietà ecc., questo metodo sembra non richiedere parametri? –

1

ho avuto una singola applicazione pagina su registrando l'URL è stato la creazione di un HashMap (usato dalla mia pagina web) che conteneva dati da più database. ho fatto le seguenti cose per caricare tutto durante server di avviare tempo-

1- Creato 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- aggiunta sotto voce nel web.xml

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

3- Nella mia classe Controller codice aggiornato per il primo controllo di Map in 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"; 

     } 

Con questa grande modifica quando avvio il mio tomcat carica dataMap durante startTime e inserisce tutto in servletContext che viene quindi utilizzato da Controller Class per ottenere risultati da servletContext già compilato.

1

Crea il tuo annotazione

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

Crea classe

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

Registrati questa classe da @Component annotazione o in XML

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

e utilizzare l'annotazione in cui si wan su qualsiasi metodo che si desidera eseguire dopo il contesto inizializzato, ad esempio:

@AfterSpringLoadComplete 
    public void init() {} 
Problemi correlati