如何将钩子添加到应用程序上下文初始化事件?

ted*_*ddy 63 model-view-controller spring applicationcontext

对于常规的Servlet,我想你可以声明一个上下文监听器,但对于Spring MVC,Spring会让这更容易吗?

此外,如果我定义一个上下文监听器然后需要访问我servlet.xml或中定义的bean,我applicationContext.xml将如何访问它们?

Bog*_*dan 98

Spring有一些你可以处理的标准事件.

为此,您必须创建并注册实现该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(...)
            // ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,你的内注册这个bean servlet.xml或applicationContext.xml文件:

<bean id="eventListenerBean" class="test.pack.age.ApplicationListenerBean" />
Run Code Online (Sandbox Code Playgroud)

当应用程序上下文初始化时,Spring将通知它.

在Spring 3中(如果您使用的是此版本),ApplicationListener该类是通用的,您可以声明您感兴趣的事件类型,并相应地过滤事件.您可以像这样简化bean代码:

public class ApplicationListenerBean implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        // now you can do applicationContext.getBean(...)
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Kumar Sambhav:这是正确的,但也必须提到差异.请参阅此处:http://stackoverflow.com/questions/5728376/spring-applicationlistener-is-not-receiving-events此处:http://forum.spring.io/forum/spring-projects/container/77684-difference -between-contextstartedevent-contextrefreshedevent (3认同)

Dav*_*mes 85

从Spring 4.2开始,您可以使用@EventListener(文档)

@Component
class MyClassWithEventListeners {

    @EventListener({ContextRefreshedEvent.class})
    void contextRefreshedEvent() {
        System.out.println("a context refreshed event happened");
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

创建注释

  @Retention(RetentionPolicy.RUNTIME)
    public @interface AfterSpringLoadComplete {
    }
Run Code Online (Sandbox Code Playgroud)

创建类

    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) {
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

通过@Component注释或xml注册此类

<bean class="ua.adeptius.PostProxyInvokerContextListener"/>
Run Code Online (Sandbox Code Playgroud)

并使用注释来处理在上下文初始化后要运行的任何方法,例如:

   @AfterSpringLoadComplete
    public void init() {}
Run Code Online (Sandbox Code Playgroud)