[英]Spring injecting or autowiring datasource bean to class
这可能是一个非常新手的问题,但是我进行了搜索,发现我的理解上有很大的差距,或者做错了一些我无法弄清楚的事情。
在我的上下文文件中,这是摘录
<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或在上下文中没有任何存在。
我知道这是一个非常基本的问题,但我正在努力解决。
感谢您的耐心等待。
如注释中所述,问题在于您是在手动创建bean,而不是让Spring容器创建它。 基本上,您正在执行以下操作:
new MyBeanOne()
因此,Spring容器无法注入您已配置的任何字段,因此为null
例如jdbcTemplate
字段。 有一些解决方案:
将您的SomeOtherClass
转换为由Spring容器管理的bean,并使其注入MyBeanOne
实例(可能使用@Autowired
批注)。
如果由于需要手动创建Bean而无法使用后一种方法,则可以如下所示手动创建Bean: 如何动态创建Spring Bean?
但是这种实现使您可以在spring config文件名的某处进行硬编码 ,并在代码中使用它。 因此,更好的方法是选择3。
查看以下解决方案: 创建新的按需Spring Bean ,在其中创建客户端抽象类,该类具有Spring将实现的方法来检索Spring托管bean的新实例。
我发现了另一种使用@Configurable
注释的方法。 通过使用此批注装饰Bean,可以按需创建Bean的新实例,Spring将为您管理Spring托管Bean的注入。 但是要实现这一点,Spring需要在幕后使用方面,而您应该为项目激活方面的使用。 解释很长,因此我提供了深入解释此解决方案的链接:
请注意,为了启用此功能 ,您必须在启动JVM时添加Java代理 , 该Java代理将在运行时使用方面来编织类。
行上的
NullPointerException
:this.jdbcTemplate.update(sql);
如果NPE实际上在那条线上,则this.jdbcTemplate
显然为null
。 如果是这样,则可以:
在Spring中没有调用setDataSource(...)
方法,可能是因为@Autowired
不正确。 添加System.out.println(...)
或在setDataSource
放置调试断点以查看是否被调用将很容易。
如果被称之为话,说不定也有多个实例abcmyBeanOne
? 您确定要从Spring上下文的另一个类中调用该实例吗? 在setDataSource
放置一个断点,并注意this
对象引用ID。 然后在this.jdbcTemplate.update(...)
行上放置一个断点,并确保this
引用ID相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.