这可能是一个非常新手的问题,但我已经搜索过,要么我的理解存在很大差距,要么我做错了,我无法弄明白。
在我的上下文文件中这是一段摘录
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
</bean>
<bean id="myBeanOne" class="a.b.c.myBeanOne">
<property name="dataSource" ref="dataSource" />
</bean>
现在在myBeanOne中我有:
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource (DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void myMethod() {
String sql = "'My generic SQL update query'";
try {
this.jdbcTemplate.update(sql);
} catch (org.springframework.dao.EmptyResultDataAccessException ex) {
}
System.exit(0);
}
当我尝试在调用setDataSource的行上执行此操作时,我收到此错误:
ERROR org.springframework.integration.handler.LoggingHandler
org.springframework.integration.MessageHandlingException:
java.lang.NullPointerException
就行:this.jdbcTemplate.update(sql);
我尝试了十种不同的配置来实现这一点,但我似乎无法做到这一点。感谢您的任何帮助。谢谢。
根据Luiggi的评论编辑:
//in yet another classes run method
myBeanOne bOne = SomeOtherClass.create(); //just returns new myBeanOne
bOne.myMethod();
SomeOtherClass或此类都不会在上下文中被归类为bean,也不会在上下文中存在。
我知道这是一个非常基本的问题,但我正在努力解决这个问题。
感谢您的耐心等待。
答案 0 :(得分:5)
如评论中所述,问题是您手动创建bean而不是让Spring容器创建它。基本上,你是这样做的:
new MyBeanOne()
因此,Spring容器无法注入您配置的任何字段,因此null
为jdbcTemplate
。 SomeOtherClass
字段。有一些解决方案:
将MyBeanOne
转换为由Spring容器管理的bean,并让它注入@Autowired
实例(可能使用@Configurable
注释)。
如果由于您需要手动创建bean而无法完成后一种方法,您可以手动创建bean,如下所示:How to create spring beans dynamically?
但是这个实现让你硬编码弹簧配置文件名并在你的代码中使用它。因此,更好的方法是选项3。
查看此解决方案:Creating New Spring Beans on Demand,您可以使用Spring实现的方法创建客户端抽象类,以检索Spring托管bean的新实例。
我找到了另一种使用{{1}}注释来处理此问题的方法。通过使用此批注装饰bean,您可以根据需要创建bean的新实例,Spring将为您管理Spring托管bean的注入。但要实现这一点,Spring需要在幕后使用方面,您应该激活项目方面的使用。解释很长,所以我提供的链接可以深入解释这个解决方案:
请注意,为了启用此功能,您必须在启动JVM时添加java代理,以便在运行时使用方面编写类。
答案 1 :(得分:0)
NullPointerException
就行:this.jdbcTemplate.update(sql);
如果NPE实际上在该行上,那么this.jdbcTemplate
显然是null
。如果是这样,那么:
在Spring中没有调用setDataSource(...)
方法,可能是因为@Autowired
不正确。可以很容易地添加System.out.println(...)
或在setDataSource
中放置调试断点以查看是否正在调用它。
如果 被调用,那么可能有多个a.b.c.myBeanOne
个实例?您是否确定从Spring上下文中从另一个类调用实例?在setDataSource
中放置一个断点并注意this
对象引用ID。然后在this.jdbcTemplate.update(...)
行放置一个断点,并确保this
reference-id相同。