Spring初学者没有可用的上下文
我正在尝试使用教程和一些东西来设置 Spring 配置。看起来一切都很好,但是当我用 @Resource 调用 Bean 的构造函数时,一切都崩溃了。
我也在尝试用 Apache Click 一石二鸟。
请问,谁能告诉我这里发生了什么以及我该如何解决这个问题?
谢谢。
错误:
Caused by: java.lang.RuntimeException: No Context available on ThreadLocal Context Stack
at org.apache.click.Context$ContextStack.peek(Context.java:934)
at org.apache.click.Context$ContextStack.access$000(Context.java:885)
at org.apache.click.Context.getThreadLocalContext(Context.java:168)
at org.apache.click.extras.control.MenuFactory.loadFromMenuXml(MenuFactory.java:495)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:302)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:255)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:197)
at org.test.pages.BasePage.<init>(BasePage.java:15)
at org.test.pages.HomePage.<init>(HomePage.java:24)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
... 30 more
这是我的 applicationContext.xml:
<context:annotation-config />
<context:component-scan base-package="org.test" />
<tx:annotation-driven />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="oracle.jdbc.OracleDriver" />
<property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.0.10:1521:xe" />
<property name="user" value="HR" />
<property name="password" value="hr"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="ctest" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
这是我的 web.xml:
<display-name>CTest</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>ClickServlet</servlet-name>
<servlet-class>org.apache.click.extras.spring.SpringClickServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ClickServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
编辑:我按照建议更改了代码,但我的 dao 仍然为空。 我还在 appContext 中放置了:
好的,我尝试 将我的 Dao 注入到我的 IndexPage 中,但在构造函数中 cTestDao 为 null。
我做错了什么?
感谢
IndexPage 类代码:
@Component @Scope("prototype")
public class IndexPage extends Page {
@Resource
protected CTestDao<Employee> cTestDao;
public IndexPage(){
super();
List<Employee> list = cTestDao.getBeans(Employee.class);
for(Employee e:list){
String s = String.format("Name:%1 Last Name:%2 Salary%3€",e.getFirstName(),e.getLastName(),e.getSalary());
System.out.println(s);
}
}
}
I'm trying to set up a Spring configuration with tutorials and some stuff. It seems everything is OK but when I call the constructor of a Bean with a @Resource everything blows up.
I'm am also giving a try to Apache Click killing two birds with one stone.
Please, can anyone tell me what happens here and how could I fix this?
Thank you.
The error:
Caused by: java.lang.RuntimeException: No Context available on ThreadLocal Context Stack
at org.apache.click.Context$ContextStack.peek(Context.java:934)
at org.apache.click.Context$ContextStack.access$000(Context.java:885)
at org.apache.click.Context.getThreadLocalContext(Context.java:168)
at org.apache.click.extras.control.MenuFactory.loadFromMenuXml(MenuFactory.java:495)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:302)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:255)
at org.apache.click.extras.control.MenuFactory.getRootMenu(MenuFactory.java:197)
at org.test.pages.BasePage.<init>(BasePage.java:15)
at org.test.pages.HomePage.<init>(HomePage.java:24)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
... 30 more
This is my applicationContext.xml:
<context:annotation-config />
<context:component-scan base-package="org.test" />
<tx:annotation-driven />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="oracle.jdbc.OracleDriver" />
<property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.0.10:1521:xe" />
<property name="user" value="HR" />
<property name="password" value="hr"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="ctest" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
This is my web.xml:
<display-name>CTest</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>ClickServlet</servlet-name>
<servlet-class>org.apache.click.extras.spring.SpringClickServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ClickServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
Edit: I changed the code as suggested but my dao is still null.
Also at the appContext I put:
<context:component-scan base-package="org.test.pages" scope-resolver="org.apache.click.extras.spring.PageScopeResolver"/>
Ok, I tried to inject my Dao in my IndexPage but in the constructor cTestDao is null.
What am i doing wrong?
Thanks
IndexPage class code:
@Component @Scope("prototype")
public class IndexPage extends Page {
@Resource
protected CTestDao<Employee> cTestDao;
public IndexPage(){
super();
List<Employee> list = cTestDao.getBeans(Employee.class);
for(Employee e:list){
String s = String.format("Name:%1 Last Name:%2 Salary%3€",e.getFirstName(),e.getLastName(),e.getSalary());
System.out.println(s);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这听起来与 Spring 完全无关,因为您的堆栈跟踪显示来自 org.apache.click 类的异常。
org.test.pages.BasePage 是做什么的?
我建议将代码精简为简单的代码,例如输出“Hello World”来测试 Spring 配置和上下文,然后添加您想要在 Web 应用程序中使用的其他库。
This sounds completely unrelated to Spring, as your stacktrace shows the exception coming from
org.apache.click
classes.What does
org.test.pages.BasePage
do?I'd suggest trimming down your code to something simple like outputting "Hello World" to test the Spring configuration and context, and then adding other libraries you'd like to use in your webapp.
这其实和Spring没有任何关系。您的
HomePage
类正在调用 Click API 上的方法,但显然不允许这样做。我建议你不要试图一石二鸟。一次学习一个框架而不尝试同时学习两个框架已经够困难的了,因为你将永远试图找出问题所在。
我建议把 Spring 排除在外,先让自己适应 Click。或者反之亦然。
This doesn't really have anything to do with Spring. Your
HomePage
class is calling a method on a Click API which it apparently isn't allowed to do.I suggest you not try to kill two birds with one stone. It's hard enough learning one framework at a time without trying to learn two at the same time, since you'll forever be trying to figure out what's going wrong.
I suggest taking Spring out of the equation, and get yourself comfortable with Click first. Or vice versa.
Click 框架文档建议对页面使用
scope = "prototype"
。如果您使用基于注释的配置,它将是:Click Framework docs suggest to use
scope = "prototype"
for pages. If you use annotation-based configuration, it will be:似乎您想要像 Spring beans 一样对待 Click 页面,换句话说,您希望 Spring 创建您的 Click 页面并注入依赖项。 Spring支持两种类型的依赖注入:通过setter方法和构造函数。在上面的示例中,您正在页面构造函数中访问 dao,但只能在构建页面后才能注入 dao。
我建议您将代码移至 Page onInit() 方法中。
或者,您可以将 DAO 注入到页面构造函数“IndexPage(CTestDao dao)”中,但我尚未测试这是否有效。
亲切的问候
鲍勃
It seems as if you want to treat Click pages like Spring beans, in other words you want Spring to create your Click page and inject the dependencies. Spring supports two types of dependency injection: through setter methods and constructor. In your example above you are accessing the dao in your Page constructor, but the dao can only be injected after the page has been constructed.
I suggest you move your code into the Page onInit() method.
Alternatively you could inject the DAO into the Page constructor "IndexPage(CTestDao dao)", but I haven't tested whether that will work or not.
Kind regards
Bob