我正在尝试在我的spring应用程序中连接到MySQL数据库。如果我使用DriverManager.getConnection(DB_URL,USER, PASS)
但无法与使用bean配置的dataSource建立连接,我可以连接到它。
应用上下文
<bean id="jdbcTest" class="org.springdemo.jdbc.JdbcTest">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
<property name="username" value="xxxx"></property>
<property name="password" value="xxxx"></property>
</bean>
类
public class JdbcTest {
private DataSource dataSource;
public JdbcTest(){
try {
Class.forName("com.mysql.jdbc.Driver");
//conn = DriverManager.getConnection(DB_URL,USER,PASS); This worked!!!!
conn = dataSource.getConnection();
stmt = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
}
public ResultSet executeQuery(String query){
//executing query; it works as I tested with DriverManager
}
public static void main(String[] args) {
AbstractApplicationContext context =
new ClassPathXmlApplicationContext("spring.xml");
JdbcTest test = context.getBean("jdbcTest", JdbcTest.class);
ResultSet rs = test.executeQuery("select * from employee");
try {
while(rs.next()){
System.out.println(rs.getString(1));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
当我使用DriverManager
时,它工作得很好但是,当我使用DataSource
对象来获取使用bean配置的连接时,它会给NullPointerException
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcTest' defined in class path resource [spring.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springdemo.jdbc.JdbcTest]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1011)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:957)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at org.springdemo.DrawingApp.main(DrawingApp.java:21)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springdemo.jdbc.JdbcTest]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:162)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1004)
... 13 more
Caused by: java.lang.NullPointerException
at org.springdemo.jdbc.JdbcTest.<init>(JdbcTest.java:47)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
... 15 more
答案 0 :(得分:2)
您无法在构造函数中访问dataSource
。 Spring首先实例化bean(在你的情况下使用默认构造函数),然后连接属性。
有a number of ways来解决这个问题。
构造函数注入
<bean id="jdbcTest" class="org.springdemo.jdbc.JdbcTest">
<constructor-arg ref="dataSource"/>
</bean>
和班级
public class JdbcTest {
private DataSource dataSource;
public JdbcTest(DataSource dataSource) throws SQLException {
this.dataSource = dataSource;
conn = dataSource.getConnection();
stmt = conn.createStatement();
}
}
<强>的InitializingBean 强>
public class JdbcTest implements InitializingBean {
private DataSource dataSource;
// setter for dataSource
public void afterPropertiesSet() {
// run the actual test
onn = dataSource.getConnection();
stmt = conn.createStatement();
}
}
初始化方法
<bean id="jdbcTest" class="org.springdemo.jdbc.JdbcTest" init-method="runTest">
<property name="dataSource" ref="dataSource"/>
</bean>
和班级
public class JdbcTest {
private DataSource dataSource;
// setter for dataSource
public void runTest() {
// run the actual test
}
}
答案 1 :(得分:1)
当使用Spring注入的DataSource时,在调用构造函数之前,DataSource不可用。基本上Spring,由于您的配置,正在执行以下操作:
JdbcTest jdbcTest = new JdbcTest(); // NPE
jdbcTest.setDataSource(dataSource);
你可能想要做的是这样的事情:
JdbcTest jdbcTest = new JdbcTest(dataSource);
为此,请将配置更新为:
<bean id="jdbcTest" class="org.springdemo.jdbc.JdbcTest">
<constructor-arg ref="dataSource"/>
</bean>
你的JdbcTest类看起来像:
public class JdbcTest {
private DataSource dataSource;
pubic JdbcTest(DataSource dataSource) throws SQLException {
this.dataSource = dataSource;
conn = dataSource.getConnection();
stmt = conn.createStatement();
}
}