歡迎大家回到《 Java教程之Spring30天快速入門》,本教程所有示例均基于Maven實現(xiàn),如果您對Maven還很陌生,請移步本人的博文《 如何在windows11下安裝Maven并配置以及 IDEA配置Maven環(huán)境》,本文的上一篇為《 全面深入詳解IOC/DI注解開發(fā)》
Spring為了使用注解簡化開發(fā),并沒有提供構(gòu)造函數(shù)注入、setter注入對應(yīng)的注解,只提供了自動裝配的注解實現(xiàn)。
1 環(huán)境準(zhǔn)備
在學(xué)習(xí)之前,把案例環(huán)境介紹下:
- 創(chuàng)建一個Maven項目
- pom.xml添加Spring的依賴
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
- 添加一個配置類SpringConfig
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
- 添加BookDao、BookDaoImpl、BookService、BookServiceImpl類
public interface BookDao {
public void save();
}
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
public interface BookService {
public void save();
}
@Service
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
- 創(chuàng)建運行類App
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookService bookService = ctx.getBean(BookService.class);
bookService.save();
}
}
最終創(chuàng)建好的項目結(jié)構(gòu)如下:
環(huán)境準(zhǔn)備好后,運行后會發(fā)現(xiàn)有問題:
出現(xiàn)問題的原因是,在BookServiceImpl類中添加了BookDao的屬性,并提供了setter方法,但是目前是沒有提供配置注入BookDao的,所以bookDao對象為Null,調(diào)用其save方法就會報控指針異常。
2 注解實現(xiàn)按照類型注入
對于這個問題使用注解該如何解決?
(1) 在BookServiceImpl類的bookDao屬性上添加@Autowired注解
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
// public void setBookDao(BookDao bookDao) {
// this.bookDao = bookDao;
// }
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
注意:
- @Autowired可以寫在屬性上,也可也寫在setter方法上,最簡單的處理方式是寫在屬性上并將setter方法刪除掉
- 為什么setter方法可以刪除呢?
- 自動裝配基于反射設(shè)計創(chuàng)建對象并通過暴力反射為私有屬性進行設(shè)值
- 普通反射只能獲取public修飾的內(nèi)容
- 暴力反射除了獲取public修飾的內(nèi)容還可以獲取private修改的內(nèi)容
- 所以此處無需提供setter方法
(2)@Autowired是按照類型注入,那么對應(yīng)BookDao接口如果有多個實現(xiàn)類,比如添加
BookDaoImpl2
@Repository
public class BookDaoImpl2 implements BookDao {
public void save() {
System.out.println("book dao save ...2");
}
}
這個時候再次運行App,就會報錯
此時,按照類型注入就無法區(qū)分到底注入哪個對象,解決方案:按照名稱注入
- 先給兩個Dao類分別起個名稱
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
@Repository("bookDao2")
public class BookDaoImpl2 implements BookDao {
public void save() {
System.out.println("book dao save ...2" );
}
}
- 此時就可以注入成功,但是得思考以下幾個問題:
- @Autowired是按照類型注入的,給BookDao的兩個實現(xiàn)起了名稱,它還是有兩個bean對象,為什么不報錯?
- @Autowired默認(rèn)按照類型自動裝配,如果IOC容器中同類的Bean找到多個,就按照變量名和Bean的名稱匹配。因為變量名叫bookDao而容器中也有一個booDao,所以可以成功注入。
- 分析下面這種情況是否能完成注入呢?
- 不行,因為按照類型會找到多個bean對象,此時會按照bookDao名稱去找,因為IOC容器只有名稱叫bookDao1和bookDao2 ,所以找不到,會報NoUniqueBeanDefinitionException
3 注解實現(xiàn)按照名稱注入
當(dāng)根據(jù)類型在容器中找到多個bean,注入?yún)?shù)的屬性名又和容器中bean的名稱不一致,這個時候該如何解決,就需要使用到@Qualifier來指定注入哪個名稱的bean對象。
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookDao1")
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
@Qualifier注解后的值就是需要注入的bean的名稱。注意:@Qualifier不能獨立使用,必須和@Autowired一起使用
4 簡單數(shù)據(jù)類型注入
引用類型看完,簡單類型注入就比較容易懂了。簡單類型注入的是基本數(shù)據(jù)類型或者字符串類型,下面在BookDaoImpl類中添加一個name屬性,用其進行簡單類型注入
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
數(shù)據(jù)類型換了,對應(yīng)的注解也要跟著換,這次使用@Value注解,將值寫入注解的參數(shù)中就行了
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
@Value("itheima")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
注意數(shù)據(jù)格式要匹配,如將"abc"注入給int值,這樣程序就會報錯。
介紹完后,會有一種感覺就是這個注解好像沒什么用,跟直接賦值是一個效果,還沒有直接賦值簡單,所以這個注解存在的意義是什么?
5 注解讀取properties配置文件
@Value一般會被用在從properties配置文件中讀取內(nèi)容進行使用,具體如何實現(xiàn)?
步驟1:resource下準(zhǔn)備properties文件
jdbc.properties
name=itheima888
步驟2: 使用注解加載properties配置文件
在配置類上添加@PropertySource注解
@Configuration
@ComponentScan("com.itheima")
@PropertySource("jdbc.properties")
public class SpringConfig {
}
步驟3:使用@Value讀取配置文件中的內(nèi)容
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
@Value("${name}")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
步驟4:運行程序
運行App類,查看運行結(jié)果,說明配置文件中的內(nèi)容已經(jīng)被加載到
注意:文章來源:http://www.zghlxwxcb.cn/news/detail-758127.html
- 如果讀取的properties配置文件有多個,可以使用@PropertySource的屬性來指定多個
@PropertySource({"jdbc.properties","xxx.properties"})
- @PropertySource注解屬性中不支持使用通配符*,運行會報錯
@PropertySource({"*.properties"})
- @PropertySource注解屬性中可以把classpath:加上,代表從當(dāng)前項目的根路徑找文件
@PropertySource({"classpath:jdbc.properties"})
6 知識點總結(jié)
知識點1:@Autowired
知識點2:@Qualifier
知識點3:@Value
知識點4:@PropertySource文章來源地址http://www.zghlxwxcb.cn/news/detail-758127.html
到了這里,關(guān)于【Spring教程十】Spring框架實戰(zhàn):全面深入詳解IOC/DI之--純注解開發(fā)模式下的依賴注入&&注解讀取properties配置文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!