【问题标题】:Spring: JDBCTemplate doesn't get injected correctly [duplicate]Spring:JDBCTemplate 没有正确注入 [重复]
【发布时间】:2018-10-08 17:40:51
【问题描述】:

似乎我在我的 Spring 项目中遇到了其他死胡同,我希望这里有人可以帮助我。

我的项目结构如下:Project structure

我的代码:

BookController

@Controller
public class BookController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String getBookData(Book book, ModelMap model) {
        model.put("data", book.getBooks());
        return "BookView";
    }
}

图书

@Component
public class Book {
    private JdbcTemplate jdbcTemplate;
    private String title;
    private String author;
    private String isbn;

    public Book() {

    }

    @Autowired
    public Book(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public ModelMap getBooks() {
        ModelMap model = new ModelMap();
        String sql = "SELECT * FROM Books";
        model.put("data", jdbcTemplate.queryForList(sql));
        return model;
    }
}

AppConfig

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"models", "controllers"})
public class AppConfig {
    @Bean
    public DriverManagerDataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/onlinelibrary");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

当我尝试在 Book getBooks() 方法中访问 jdbcTemplate 时,我遇到了一个空指针异常。这本质上就像依赖注入根本不起作用。

提前感谢您的帮助!

【问题讨论】:

  • 您不需要Book 类中的默认构造函数,也不需要另一个构造函数上的@Autowired 注释。有关详细信息,请参阅here。另外,一般来说,构造函数注入更好。而且我不确定您是否需要 @ComponentScan 注释。
  • 我确实需要默认构造函数。如果我删除它,在执行中我会得到一个异常,因为没有找到默认构造函数。无论如何,我从构造函数中删除了@Autowired,但是当我尝试在Book getBooks() 方法中访问jdbcTemplate 时,我得到了NullPointerException。有任何想法吗? PS:我相应地编辑了主题。
  • 因为您将Book 作为方法参数注入,这使得它不是弹簧管理的bean。它应该是实例级属性。此外,您正在使用 Spring Boot,它已经创建了 DataSourceJdbcTemplate,启用 web 进行组件扫描,因此删除 AppConfig 类。
  • 请不要一遍又一遍地问[同一个问题]。

标签: spring spring-mvc spring-boot dependency-injection


【解决方案1】:

请在 Book 中使用@Autowired,以便 Spring 可以注入实际的 Object。

@Component
public class Book {

    @Autowired
    private JdbcTemplate jdbcTemplate;
}

【讨论】:

  • 将@Autowired 放在public class Book 之前没有意义。我不想注入它,我只想让它成为一个 bean(使用 @Component 完成)。
  • 是的,将 JDBCTemplate 放入 Book 中没有任何意义。创建另一个 DAO 将其标记为存储库并在那里使用 JDBCTemplate。请参阅我的新答案。
【解决方案2】:
@Repository
public class BookDAO {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<Book> findAllBooks(){

        return jdbcTemplate.query("SELECT * FROM Books",new BeanPropertyRowMapper(Book.class)); //BeanPropertyRowMapper can be used when propertyname canbe derived from column name
    }
}

public class Book implement Serializable{
    private String title;
    private String author;
    private String isbn;

    public Book() {

    }
    //all getter setter
}

【讨论】:

    猜你喜欢
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 1970-01-01
    • 2015-08-30
    相关资源
    最近更新 更多