java 未调用 applicationContextProvider
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5133291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
applicationContextProvider is not being called
提问by Dejell
I am using Spring 3.0.3.
我正在使用 Spring 3.0.3。
I would like to use the applicationContextProvider so I declared:
我想使用 applicationContextProvider 所以我声明:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="applicationContextProvider" class="com.mycompany.util.ApplicationContextProvider"></bean>
<context:annotation-config/>
<tx:annotation-driven/>
</beans>
and my ApplicationContextProvider:
和我的 ApplicationContextProvider:
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public void setApplicationContext(ApplicationContext _applicationContext) throws BeansException {
applicationContext = _applicationContext;
}
}
But the set is never being called!
但是永远不会调用该集合!
and whenever I am using ApplicationContextProvider.getApplicationContext()
returns null.
每当我使用ApplicationContextProvider.getApplicationContext()
返回空值。
why is it?
为什么?
采纳答案by David Victor
Part of the problem may be that your getter is static. So its possible for you to call it before Spring has created an instance of ApplicationContextProvider.
部分问题可能是您的 getter 是静态的。因此,您可以在 Spring 创建 ApplicationContextProvider 的实例之前调用它。
You need to refer to the bean 'applicationContextProvider' that Spring has created for you when Spring is "ready" for you to use it. See Bean lifecycle
当 Spring 准备好供您使用时,您需要引用 Spring 为您创建的 bean 'applicationContextProvider'。查看Bean 生命周期
E.g. via a Junit test with your bean in 'app-context.xml' in src/test/resources
例如,通过在 src/test/resources 中的“app-context.xml”中使用您的 bean 进行 Junit 测试
package com.mycompany.util;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration(locations="classpath:app-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class ApplicationContextProviderTest {
@Autowired // Injected by Spring when bean is "ready"
ApplicationContextProvider contextProvider;
@Test
public void testContext() {
assertNotNull(contextProvider);
ApplicationContext context = ApplicationContextProvider.getApplicationContext();
assertNotNull(context);
System.out.println("My context has " + context.getBeanDefinitionCount() + " beans");
}
}
Then this gets a green bar for applicationContext being set.
然后这将获得一个用于设置 applicationContext 的绿色条。
Example output (don't leave System.out in the test btw).
示例输出(顺便说一句,不要将 System.out 留在测试中)。
INFO : org.springframework.test.context.TestContextManager - @TestExecutionListeners is not present for class [class com.mycompany.util.ApplicationContextProviderTest]: using defaults.
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [app-context.xml]
INFO : org.springframework.context.support.GenericApplicationContext - Refreshing org.springframework.context.support.GenericApplicationContext@4c331059: startup date [Sun Feb 27 13:38:13 GMT 2011]; root of context hierarchy
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4b1c2b67: defining beans [applicationContextProvider,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy
My context has 5 beans
INFO : org.springframework.context.support.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@4c331059: startup date [Sun Feb 27 13:38:13 GMT 2011]; root of context hierarchy
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4b1c2b67: defining beans [applicationContextProvider,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy
app-context.xml:
应用上下文.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="applicationContextProvider" class="com.mycompany.util.ApplicationContextProvider"></bean>
</beans>
回答by Tomasz Nurkiewicz
Seems like you are doing something the wrong way here... Do you want to get access to Spring beans from object not managed by Spring? How about WebApplicationContextUtils:
似乎您在这里做错了一些事情……您想从不受 Spring 管理的对象访问 Spring beans 吗?WebApplicationContextUtils怎么样:
WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
But WebApplicationContextUtils
should always be treated as a last resort because this is not a Spring way. Are you sure you cannot integrate web services with Spring somehow? For instance with Apache CXF one can simply implement WS endpoint as a Spring bean or inject client proxy to other beans...
但WebApplicationContextUtils
应始终作为最后的手段,因为这不是Spring 的方式。您确定不能以某种方式将 Web 服务与 Spring 集成吗?例如,使用 Apache CXF 可以简单地将 WS 端点实现为 Spring bean 或将客户端代理注入其他 bean...
Using static fields is always asking yourself for trouble. I am sure you can achieve your goals in a more elegant fashion.
使用静态字段总是自找麻烦。我相信你可以以更优雅的方式实现你的目标。
回答by nidalpres
This is an old question with already accepted answer, but for me it wasn't really clear why the setApplicationContext()
method wasn't being called on the applicationContextProvider
. The answer provided howbut really not the why.
这是一个已经接受答案的老问题,但对我来说,为什么setApplicationContext()
没有在applicationContextProvider
. 答案提供了如何,但实际上不是为什么。
Spring creates beans using lazy strategy: a bean will only be created the first time it is needed. That is why example in the accepted answer works: the bean is needed by ApplicationContextProviderTest
and so it is created at that point, and not before, and setApplicationContext()
method is being called at that point in time and everything works as intended.
Spring 使用惰性策略创建 bean:仅在第一次需要时才会创建 bean。这就是为什么接受的答案中的示例有效的原因:bean 是需要的ApplicationContextProviderTest
,因此它是在那个时候创建的,而不是在此之前创建,并且setApplicationContext()
在那个时间点调用方法并且一切都按预期工作。
However, if your bean is not auto-wired anywhere none of this will happen. In this case the solution is to tell Spring to not use lazy instantiation, i.e.:
但是,如果您的 bean 没有在任何地方自动连接,这些都不会发生。在这种情况下,解决方案是告诉 Spring 不要使用惰性实例化,即:
<bean id="applicationContextProvider" lazy-init="false" class="com.mycompany.util.ApplicationContextProvider" />
This way, the bean will be created on application startup and method setApplicationContext()
will be called at that time. You can then use the bean afterwords, provided that the usagehappens after application startup is done.
这样,bean 将在应用程序启动时创建,setApplicationContext()
届时将调用方法。然后,您可以使用bean后记,前提是使用应用程序启动完成后会发生。
Of course, much better way is to auto-wire the bean wherever you need it, but sometime it is not possible (read: legacy apps).
当然,更好的方法是在您需要的任何地方自动连接 bean,但有时这是不可能的(阅读:遗留应用程序)。