我正在学习春天。我使用Spring和JDBC,并阅读有关自动装配的内容。
所以我写了这个
public class JdbcAccess {
@Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
System.out.println("setDataSource called");
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void getCount1() {
String sql= "SELECT COUNT(*) FROM MYTABLE";
jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(getDataSource());
int count = jdbcTemplate.queryForInt(sql);
System.out.println("Result is = " + count);
}
public void getCount2() {
String sql= "SELECT COUNT(*) FROM MYTABLE";
int count = jdbcTemplate.queryForInt(sql); // Line 66
System.out.println("Count = " + count);
}
}
我希望以下作为输出:
setDataSource called
Count = 3
我得到了什么:
Exception in thread "main" java.lang.NullPointerException at playwithspring.JdbcAccess.getCount2(JdbcAccess.java:66)
这意味着setDataSource(..)
没有被Spring调用,但Spring框架正在正确设置数据源,因为调用getCount1()
的{{1}}运行正常。所以我的问题是:
请注意:我运行getDataSource()
或getCount1()
答案 0 :(得分:4)
而不是
现场注入
@Autowired
private DataSource dataSource;
如果你想要调用setter,那么USE Setter Injection 而不是Field注入。
@Autowired
public void setDataSource(DataSource dataSource) {
System.out.println("setDataSource called");
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
答案 1 :(得分:2)
异常的原因是因为Spring没有调用setDataSource
,因为Spring使用反射来设置数据源。
您有两个很好的选项来设置它,或者使用@Autowired注释您的setter方法,或者您可以将当前注释保留在dataSource变量上并使用@PostConstruct注释来初始化您的jdbcTemplate
我认为会导致一个更干净的代码。
@Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@PostConstruct
private void init() {
jdbcTemplate = new JdbcTemplate(dataSource);
System.out.println("jdbTemplate created");
}
public void getCount2() {
String sql= "SELECT COUNT(*) FROM MYTABLE";
int count = jdbcTemplate.queryForInt(sql);
System.out.println("Count = " + count);
}