IoC 註解
使用註解建立物件之後,就不用像之前那樣透過bean標籤手動配置建立物件的屬性了。
註解要寫在需要注入的類或者成員方法前。
按作用分為四類:
建立物件
- 和 bean 標籤功能一樣
- @Component - 把當前物件存入 spring 容器
- 屬性:value: 指定 bean 的 id,預設值是當前類名,但首字母要小寫
- 衍生註解:使三層物件更加清晰,相當於@Component的子類
- @Controller:表現層
- @Service:業務層
- @Repository:持久層
在 bean.xml 中配置 context 名稱空間
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置 component 註解所需的標籤 -->
<context:component-scan base-package="spring.selflearning"></context:component-scan>
</beans>
注入資料
- 和 property 功能一樣
- @Autowired: 自動按照型別注入資料,只要容器中有唯一的一個bean物件型別和要注入的變數型別匹配,就能注入成功。
- 可以出現在變數上,也可以出現在方法上。
- 此時無需set方法
- @Qualifier:按照型別注入的基礎上再按照名稱注入。給類成員注入時不能單獨使用,給方法引數注入時可以。
- @Value:注入基本型別和String型別
- 集合型別注入只能透過xml實現
- 改變作用範圍
- 和 scope 一樣
- @Scope,取值可以是 singleton 或 prototype
- 生命週期相關
- 和 init-method 和 destroy-method 作用一樣
- @PreDestroy 銷燬
- @PostConstruct 初始化
- 需要用 close() 方法釋放容器
- 只能銷燬單例物件
Spring 的一些新註解
這些新註解功能和bean.xml中的一些屬性功能相同,為的是取代bean.xml中的配置方式。
@Configuration
- 表示當前類是個配置類
- 當配置類作為AnnotationConfigApplicationContext物件建立的引數時,該註解可以不寫。
如某個方法中使用ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
建立物件,那麼無需在方法上使用@Configuration註解,因為Java會自動找到SpringConfiguration.class
這個配置類建立物件。
AnnotationConfigApplicationContext
方法中可以寫多個配置類,用逗號分隔。
@ComponentScan
- 指定spring建立容器時需要掃描的包;屬性:basePackages
- 功能和
<context:component-scan base-package="spring.selflearning"></context:component-scan>
一樣。
@Bean
- 把當前方法的返回值作為bean物件存入ioc容器中;屬性:name,指定bean的id,不寫時預設值為當前方法的名稱
- 如果bean註解有值,spring會去容器中查詢是否有可用的bean物件,查詢方式和AutoWired註解的功能一樣
如給建立一個QueryRunner物件的方法新增註解:
@Bean(name = "runner")
@Scope("prototype")
public QueryRunner createQueryRunner(DataSource dataSource) {
return new QueryRunner(dataSource);
}
@Import
- 指定其他配置類的位元組碼
- 使用Import註解之後的類就是父配置類,匯入的是子配置類。此時建立物件時只需註解父類配置類即可。
PropertySource
- 用於指定properties的位置
- @Value:指定檔案路徑和名稱,classpath,表示在類路徑下
- 在我實際使用中,發現Value註解無法正常讀取properties配置檔案,目前這個問題還沒解決。附自己的程式碼:
父配置類:SpringConfiguration.java
@ComponentScan(basePackages = "spring.selflearning") // 屬性是陣列型別,如果需要掃描多個類則需加大括號
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbcConfig.properties")
public class SpringConfiguration {}
子配置類:JdbcConfig.java
package config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.sql.DataSource;
@Component("jdbcConfig")
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
public String getDriver() {
return driver;
}
public String getUrl() {
return url;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
@Bean(name = "runner")
@Scope("prototype")
public QueryRunner createQueryRunner(DataSource dataSource) {
return new QueryRunner(dataSource);
}
@Bean(name = "dataSource")
public DataSource createDataSource() {
try {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass(driver);
ds.setJdbcUrl(url);
ds.setUser(username);
ds.setPassword(password);
return ds;
}
catch(Exception e) {
throw new RuntimeException(e);
}
}
}
jdbcConfig.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=1234
關於何時使用 xml,何時使用註解
實際上註解並不總是能減少配置過程中的程式碼量,如配置JDBC連線時。
配置注入的物件在別人寫好的類中,那麼使用xml更好;如果是自己寫的類,直接在類中新增註解則更為方便。
本作品採用《CC 協議》,轉載必須註明作者和本文連結