Spring:为什么尽管@Autowired注释没有调用setter

时间:2016-09-08 10:31:21

标签: java spring

我正在学习春天。我使用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}}运行正常。所以我的问题是:

  • 然后 Spring如何设置dataSource 而不调用setter?
  • 我可以做什么在上述计划中实现所需输出

请注意:我运行getDataSource()getCount1()

2 个答案:

答案 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);
}