简体   繁体   中英

Dependency Injection of datasource and jdbctemplate?

I am very new to webapp development in general and Spring framework in particular. I am following this Spring JDBC Transactions tutorial But instead of accessing the db service from only one class, I wish to access it from multiple classes.

In the tutorial the service is defined like this

public class BookingService {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Transactional
    public void book(String... persons) {
        for (String person : persons) {
            System.out.println("Booking " + person + " in a seat...");
            jdbcTemplate.update("insert into BOOKINGS(FIRST_NAME) values (?)", person);
        }
    };

    public List<String> findAllBookings() {
        return jdbcTemplate.query("select FIRST_NAME from BOOKINGS", new RowMapper<String>()     
            @Override
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getString("FIRST_NAME");
            }
        });
    }

}

These are the Beans

@Configuration
@EnableTransactionManagement
@EnableAutoConfiguration
public class Application {

@Bean
BookingService bookingService() {
    return new BookingService();
}

@Bean
DataSource dataSource() {
    return new SimpleDriverDataSource() {{
        setDriverClass(org.h2.Driver.class);
        setUsername("sa");
        setUrl("jdbc:h2:mem");
        setPassword("");
    }};
}

@Bean
JdbcTemplate jdbcTemplate(DataSource dataSource) {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    System.out.println("Creating tables");
    jdbcTemplate.execute("drop table BOOKINGS if exists");
    jdbcTemplate.execute("create table BOOKINGS(" +
            "ID serial, FIRST_NAME varchar(5) NOT NULL)");
    return jdbcTemplate;
}

They instantiated the service in only the Application class and did all the transactions there

ApplicationContext ctx = SpringApplication.run(Application.class, args);
BookingService bookingService = ctx.getBean(BookingService.class);

//bookingService.doStuff()

In my test project, I copied the same Bean definitions but I performed the transactions in multiple classes.

public class foo {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(Application.class);
    BookingService bookingService = ctx.getBean(BookingService.class);
    bookingService.book(...);
    // some other stuff
}

public class bar {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(Application.class);
    BookingService bookingService = ctx.getBean(BookingService.class);
    bookingService.findAllBookings(...);
    // some other stuff
}

It seems that when I perform all transactions in one class only (for example, book and find in foo class) it performs as expected. But when I try to separate them into multiple classes it doesn't behave as expected. If I perform the book in foo, I cannot find in bar. What concept am I missing? Am I instantiating multiple instances of the datasource and jdbctemplate because I instantiated the service multiple times. But I thought Spring handles the injection? And since there is only one physical database then there would only be one instance of datasource and jdbctemplate. What concept did I misunderstood? Please help and point me to the right direction. Thanks.

You need to inject your dependencies, for example:

public class Foo {

    @Autowired
    private BookingService bookingService;

    public doStuff() {
        bookingService.book(...);
        // some other stuff
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM