如果有碰過Spring專案應該會發現annotation與xml設定的方式會混用(比如明天會看到的Spring MVC),但走到Spring boot你就會發現都會是annotaion配置方式了,先理解xml的設定方式有助於我們更快熟悉annotation設定方式,今日我們將嘗試全部使用Annotation的方式來配置物件。
我們沿用day24的module,在原有的package創建com.swj.annotation,好讓讀者與原先的com.swj.xml做比較
翻譯作刻板印象註解,在系統架構分層中可以讓我們清楚了解物件是在哪一層主要負責的功能,其實就是寫給開發人員看的。Spring並不會區分這些註解,當在IDE中點選這些註解會發現背後其實都是@Component。
它只能在方法上註解,通常會設定在有@Configuration的class中,它可以在同一個class中引用其他@Bean的方法,請參考官方API說明。
@Configuration
public class AppConfig {
@Bean
public FooService fooService() {
return new FooService(fooRepository());
}
@Bean
public FooRepository fooRepository() {
return new JdbcFooRepository(dataSource());
}
// ...
}
配置文件註解,想成是前一天範例的beans.xml。只是Spring container生成時引用不同的設定檔,通常會與@ComponentScan合併使用,告訴Container哪個package下的物件也需要納管。
//生成spring container use xxx.class
AnnotationConfigApplicationContext container = new AnnotationConfigApplicationContext(SpringConfig.class);
//生成spring container use xml
ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext("beans.xml");
TestAnnotation
public class TestAnnotation {
public static void main(String[] args) throws SQLException {
AnnotationConfigApplicationContext container = new AnnotationConfigApplicationContext(SpringConfig.class);
User bean = container.getBean(User.class);
System.out.println(bean);
UserController controller = container.getBean(UserController.class);
controller.doUserController();
}
}
SpringConfig
@Configuration
@ComponentScan(value = "com.swj.annotation")
public class SpringConfig {
@Bean
public User user() {
return new User("joe", "1234"); // 注入默认值
}
}
DbConfig
透過@PropertySource引入外部設定檔
透過@Value與${}設定參數檔資訊
@Configuration
@PropertySource("classpath:dbConfig.properties") // 引入外部設定檔
public class DbConfig {
// 引用設定檔資訊
@Value("${db.driverClassName}")
private String driverClassName;
@Value("${db.url}")
private String url;
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
@Value("${db.hikari.maximumPoolSize}")
private int maximumPoolSize;
@Value("${db.hikari.minimumIdle}")
private int minimumIdle;
@Value("${db.hikari.idleTimeout}")
private long idleTimeout;
@Value("${db.hikari.connectionTimeout}")
private long connectionTimeout;
@Value("${db.hikari.maxLifetime}")
private long maxLifetime;
// Config HikariCP
@Bean
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setJdbcUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setMaximumPoolSize(maximumPoolSize);
dataSource.setMinimumIdle(minimumIdle);
dataSource.setIdleTimeout(idleTimeout);
dataSource.setConnectionTimeout(connectionTimeout);
dataSource.setMaxLifetime(maxLifetime);
return dataSource;
}
}
User
public class User {
private String name;
private String userId;
public User(String name, String userId) {
this.name = name;
this.userId = userId;
//省略getter setter toString
}
}
UserController
@Controller
public class UserController {
private UserService userService;
public void doUserController() throws SQLException {
System.out.println("in doUserController");
userService.doUserService();
}
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
}
UserService
@Service
public class UserService {
private UserDao userDao;
public void doUserService() throws SQLException {
System.out.println("invoke doUserService");
userDao.doUserDao();
}
@Autowired
public UserService(UserDao userDao) {
this.userDao = userDao;
}
}
UserDao
@Repository
public class UserDao {
private DataSource dataSource;
public void doUserDao() throws SQLException {
System.out.println("invoke doUserDao");
System.out.println("dataSource info:"+dataSource.getConnection());
}
@Autowired
public UserDao(DataSource dataSource) {
this.dataSource = dataSource;
}
}
Demo