对于一个普通的Servlet,我想你可以声明一个context listener,但是对于Spring MVC,Spring会使这更简单吗?此外,如果我定义一个上下文侦听器,然后需要访问我的servlet.xml
或applicationContext.xml
中定义的bean,我将如何访问它们?如何将钩子添加到应用程序上下文初始化事件?
回答
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.xml
或applicationContext.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(...)
// ...
}
}
从Spring 4.2可以使用@EventListener
(documentation)
@Component
class MyClassWithEventListeners {
@EventListener({ContextRefreshedEvent.class})
void contextRefreshedEvent() {
System.out.println("a context refreshed event happened");
}
}
如何打印属性等,这种方法似乎没有参数? – 2018-03-02 16:20:11
我对输入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中获取结果。
通过@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() {}
- 1. 当上下文初始化时,JSF初始化应用程序bean
- 2. 如何将ActiveRecord添加到未经ActiveRecord初始化的Rails应用程序中?
- 3. 应用程序上下文中的地图映射初始化
- 4. HybrisContextFactory - 初始化全局应用程序上下文时出错
- 5. 如何将文件上传添加到Rails应用程序?
- 6. 在对象初始化期间添加事件处理程序
- 7. 初始化后添加backbone.js事件
- 8. 如何当应用程序初始化
- 9. 应用程序初始化
- 10. 如何将上下文添加到Sequelize挂钩?
- 11. 将[FIRApp configure]添加到您的应用程序初始化错误
- 12. 如何初始化上下文?
- 13. 如何将侦听器添加到JSF会话初始化事件?
- 14. Rails 3.如何添加文件到初始化?
- 15. 如何将mongrel.rb附加到Redmine的初始化程序中?
- 16. 将多个上下文根添加到单个应用程序
- 17. Spring上下文初始化
- 18. 如何将初始UIViewController添加到现有的COreData应用程序?
- 19. 如何在应用程序初始化之前在Flex中预加载文件
- 20. 从ASP.NET应用程序调试HTTP模块初始化事件
- 21. 初始化WPF/Prism应用程序中的事件
- 22. 如何在应用程序启动时初始化已添加的应用程序小部件?
- 23. 如何将javadoc添加到Java中的静态初始化程序中?
- 24. 如何初始化JMS中的初始上下文
- 25. 在Tomcat6上运行的Grails应用程序 - 上下文初始化失败
- 26. 在应用程序初始化后添加角度离子视图和路线
- 27. Python的钩子模块初始化
- 28. Karma是否有初始化钩子?
- 29. 如何将我的Android应用程序中的原始文件夹添加到子文件夹?
- 30. 使用对象初始化程序初始化对象时添加DataCollection属性
好的,谢谢。很高兴知道spring3过滤事件。我之前注意到applicationlistener类。但它的钩子也将被调用RequestHandledEvent。 – 2012-01-11 00:16:07
任何想法如果你使用注释的东西会发生什么,并且你声明了两个类?非注释(XML)和两个?他们会按照宣布的顺序开火吗?谢谢;) – momomo 2012-06-12 14:28:45
仅供参考,事件的上下文开始是ContextStartedEvent 文档: - http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/context/event/ContextStartedEvent。 html – 2013-09-12 10:51:08