2011-12-31 21 views

Respuesta

82

Spring has some standard events which you can handle.

Para ello, debe crear y registrar un bean que implementa la interfaz ApplicationListener, algo como esto:

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

A continuación, se registra este bean dentro de su archivo servlet.xml o applicationContext.xml:

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

y Spring lo notificará cuando se inicialice el contexto de la aplicación.

En el resorte 3 (si está utilizando esta versión), el ApplicationListener class is generic y puede declarar el tipo de evento que le interesa, y el evento se filtrará en consecuencia. Se puede simplificar un poco el código de grano de la siguiente manera:

public class ApplicationListenerBean implements ApplicationListener<ContextRefreshedEvent> { 

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

bien, gracias.es bueno saber que spring3 filtra los eventos. Me di cuenta de la clase applicationlistener antes. pero sus ganchos también se llamarían para RequestHandledEvent. –

+0

¿Alguna idea de qué pasará si usa las anotaciones y declara dos clases? No anotación (XML) y dos? ¿Dispararán en el orden declarado? gracias;) – momomo

+0

Solo como información, evento para el contexto iniciado es ContextStartedEvent Documentos: - http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/context/event/ContextStartedEvent. html –

58

desde la primavera de 4,2 se puede utilizar @EventListener (documentation)

@Component 
class MyClassWithEventListeners { 

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

¿cómo imprimo propiedades, etc., este método parece no tener params? –

1

que tenía una sola aplicación página en introducir la URL que estaba creando un HashMap (utilizado por mi página web) que contenía datos de múltiples bases de datos. Yo siguientes cosas para cargar todo durante el inicio del servidor tiempo-

1- Creado 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- Añadido por debajo de la entrada en web.xml

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

3- En mi clase controlador código actualizado para la primera comprobación de Mapa en 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 este cambio cuando inicio mi tomcat, carga dataMap durante startTime y pone todo en servletContext que luego usa Controller Class para obtener resultados del servletContext ya poblado.

1

Cree su anotación

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

Crear clase

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

Registro esta clase por @Component anotación o en XML

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

y utilizar la anotación donde WAN en cualquier método que Desea ejecutar después de que se inicializó el contexto, como:

@AfterSpringLoadComplete 
    public void init() {} 
Cuestiones relacionadas