05-常用IOC注解按照作用分类
生活随笔
收集整理的這篇文章主要介紹了
05-常用IOC注解按照作用分类
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
- Sprin 基于注解的 IOC 以及 IOC 案例
- 一、注解分類
- 1.用于創建對象的
- 2.用于注入數據的
- 3.用于改變作用范圍的
- 4.和生命周期相關
- 二、 bean.xml 配置
- 三、注解配置接口與實現類代碼
- 1.結構圖
- 2. IAccountService
- 3. AccountServiceImpl
- 4. Client 主函數
- 5.由 Component 衍生的注解
- 四、自動按照類型注入
- 1.@AutoWired
- 問題
- 2. @Qualifier
- 3. @Resource(name="")
- 1.@AutoWired
- 五、用于改變作用范圍的
- 1. AccountServiceImpl 實現類
- 2. Client 主函數
- 六.和生命周期相關
- 1.實現類
- 2.Client
Sprin 基于注解的 IOC 以及 IOC 案例
- 持久層技術選擇:dbutils
- spring 的一些新注解使用
明確:寫在前面
學習基于注解的 IOC 配置,大家腦海里首先得有一個認知,即注解配置和 xml 配置要實現的功能都是一樣的,都是要降低程序間的耦合。只是配置的形式不一樣。
關于實際的開發中到底是用 xml 還是注解,每家公司有著不同的使用習慣,所以這兩者配置方式我們都需要掌握。
在講解注解配置時,采用上一章案例,吧 spring 的 xml 配置內容改為使用注解逐步實現。
一、注解分類
1.用于創建對象的
- 他們的作用和在 xml 配置文件中編寫一個 標簽實現的功能是一樣的
- @Component:
- 作用:用于把當前類對象存入 spring 容器中
- 疑惑,spring 容器為 map 結構,那它對應的值呢?
- 屬性:
- value:用于指定 bean 的 id。當我們不寫時,他的默認值是當前類名,且首字母改小寫。
- 屬性:
- @Controller:一般用于表現層
- @Service:一般用于業務層
- @Repository:一般用于持久層
- @Repository
- 以上三個注解它們的做哦那個和屬性與 Component 是一模一樣的。
- 他們三個是 spring 框架為我們提供明確的三層使用的注解,使我們的三層對象更加清晰
2.用于注入數據的
- 他們的作用和在 xml 配置文件中編寫一個 標簽實現的功能是一樣的
- @Autowired:
- 作用:
- 自動按照類型注入。只要容器中有唯一的 bean 對象類型和要注入的變量類型匹配,就可以注入成功。
- 如果 IOC 容器中沒有任何 bean 的類型和要注入的變量類型匹配,則報錯。
- 如果 IOC 容器中有多個類型匹配時:
- 出現位置:可以是變量上,也可以是方法上
- 細節:咋使用注解注入時,set 方法就不是必須的了。
- 作用:
- @Qualifier:
- 作用:
- 在按照類中注入的基礎之上再按照名稱注入。他在給類成員注入時不能單獨使用。但是再給方法參數注入時可以。
- 屬性:
- value:用于指定注入 bean 的 id
- 作用:
- @Resource:
- 作用:
- 直接按照 bean 的 id 注入。它可以獨立使用
- 屬性:
- name:用于指定 bean 的 id
- 作用:
- 注意:
- 以上三個注入都只能注入其他 bean 類型的數據,而基本類型和 String 類型無法使用上述注解實現。
- 另外,集合類型的注入只能通過 XML 來實現
- @Value
- 作用:
- 用于注入基本類型和 String 類型的數據
- 屬性:
- value:用于指定數據的值。它可以使用 spring 中 SpEL (也就是 spring 的 el 表達式),SpEL的寫法:${表達式}
- 作用:
3.用于改變作用范圍的
- 他們的作用和在 bean 標簽中使用 scope 屬性實現的功能是一樣的
- Scope:
- 作用:
- 用于注入基本類型和 String 類型的數據
- 屬性:
- value:指定范圍的取值。常用取值:singleton(默認),prototype
- 作用:
4.和生命周期相關
- 他們的作用和在 bean 標簽中使用 init-method 和 destroy-method 的作用是一樣的
- PreDestroy
- 作用:用于指定銷毀方法
- PostConstruct
- 作用:用于指定初始化方法
二、 bean.xml 配置
spring-core路勁 按住 ctrl + f 搜索 xmlns: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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><!--告知 spring 在創建容器時要掃描的包,配置所需要的標簽不是在 beans 的約束中,而是一個名稱為 context 名稱空間和約束中--><context:component-scan base-package="com"/> </beans>三、注解配置接口與實現類代碼
1.結構圖
2. IAccountService
public interface IAccountService {void saveAccount(); }3. AccountServiceImpl
//@Component(value = "accountServiceImpl") 指定 id @Component public class AccountServiceImpl implements IAccountService {private IAccountDao accountDao;public AccountServiceImpl(){System.out.println("AccountServiceImpl 對象創建了");}public void saveAccount() {accountDao.saveAccount();} }4. Client 主函數
public class Client {public static void main(String[] args) {//1.獲取核心容器對象ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");//2.根據 id 獲取 bean 對象IAccountService as=ac.getBean("accountServiceImpl",IAccountService.class);System.out.println(as);}}5.由 Component 衍生的注解
- @Controller:一般用于表現層
- @Service:一般用于業務層
- @Repository:一般用于持久層
- 以上三個注解它們的做哦那個和屬性與 Component 是一模一樣的。
- 他們三個是 spring 框架為我們提供明確的三層使用的注解,使我們的三層對象更加清晰
四、自動按照類型注入
1.@AutoWired
接下來我們調用方法
public class Client {public static void main(String[] args) {//1.獲取核心容器對象ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");//2.根據 id 獲取 bean 對象IAccountService as=ac.getBean("accountServiceImpl",IAccountService.class);System.out.println(as);as.saveAccount();} }結果為空指針異常
AccountServiceImpl 對象創建了 com.service.Impl.AccountServiceImpl@1f010bf0 Exception in thread "main" java.lang.NullPointerExceptionat com.service.Impl.AccountServiceImpl.saveAccount(AccountServiceImpl.java:26)at com.ui.Client.main(Client.java:24)- 用于注入數據的
- 他們的作用和在 xml 配置文件中編寫一個 標簽實現的功能是一樣的
- @Autowired:
- 作用:
- 自動按照類型注入。只要容器中有唯一的 bean 對象類型和要注入的變量類型匹配,就可以注入成功。
- 如果 IOC 容器中沒有任何 bean 的類型和要注入的變量類型匹配,則報錯。
- 如果 IOC 容器中有多個類型匹配時:
- 出現位置:可以是變量上,也可以是方法上
- 細節:咋使用注解注入時,set 方法就不是必須的了。
- 作用:
結果可以正常輸出
問題
如果不止一個 IAccountDao 的實現類,而是有多個怎么辦?
@Repository("accountDao1") public class AccountDaoImpl implements IAccountDao {public void saveAccount() {System.out.println("保存了");} } @Repository("accountDao2") public class AccountDaoImpl2 implements IAccountDao {public void saveAccount() {System.out.println("保存了");} }運行結果出錯
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.dao.IAccountDao' available: expected single matching bean but found 2: accountDao1,accountDao2解決:
修改 AccountServiceImpl 中 IAccountDao 數據類型的變量名 為 accountDao1,運行結果成功
@Service(value = "accountServiceImpl") public class AccountServiceImpl implements IAccountService {@Autowiredprivate IAccountDao accountDao1;public AccountServiceImpl(){System.out.println("AccountServiceImpl 對象創建了");}public void saveAccount() {accountDao1.saveAccount();} }2. @Qualifier
@Qualifier:
- 作用:
- 在按照類中注入的基礎之上再按照名稱注入。他在給類成員注入時不能單獨使用。但是再給方法參數注入時可以。
- 屬性:
- value:用于指定注入 bean 的 id
3. @Resource(name="")
@Resource:
- 作用:直接按照 bean 的 id 注入。它可以獨立使用
- 屬性:
- name:用于指定 bean 的 id
五、用于改變作用范圍的
1. AccountServiceImpl 實現類
@Service(value = "accountServiceImpl") @Scope(value = "prototype") public class AccountServiceImpl implements IAccountService {/* @Autowired@Qualifier("accountDao1")*/@Resource(name = "accountDao2")private IAccountDao accountDao;public AccountServiceImpl(){System.out.println("AccountServiceImpl 對象創建了");}public void saveAccount() {accountDao.saveAccount();} }2. Client 主函數
public class Client {public static void main(String[] args) {//1.獲取核心容器對象ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");//2.根據 id 獲取 bean 對象IAccountService as1=ac.getBean("accountServiceImpl",IAccountService.class);IAccountService as2=ac.getBean("accountServiceImpl",IAccountService.class);System.out.println(as1==as2);} }六.和生命周期相關
1.實現類
@Service(value = "accountServiceImpl") @Scope(value = "prototype") public class AccountServiceImpl implements IAccountService {/* @Autowired@Qualifier("accountDao1")*/@Resource(name = "accountDao2")private IAccountDao accountDao;@PostConstructpublic void init(){System.out.println("初始化方法執行了");}@PreDestroypublic void destroy(){System.out.println("銷毀方法執行");}public void saveAccount() {accountDao.saveAccount();} }2.Client
public class Client {public static void main(String[] args) {//1.獲取核心容器對象ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");//2.根據 id 獲取 bean 對象IAccountService as1=ac.getBean("accountServiceImpl",IAccountService.class);ac.close();} }為什么這么寫?
ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");如果你把一個子類看作父類,那么就只能調用父類的方法,這個時候就不能調用 close() 方法
注意:
然而結果并沒有調用銷毀方法,這是因為這是一個多例對象,看實現類上面 @Scope(value = "prototype") ,多例對象銷毀 spring 是不負責的,所以應該改為單例對象。
轉載于:https://www.cnblogs.com/zuiren/p/11429714.html
總結
以上是生活随笔為你收集整理的05-常用IOC注解按照作用分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 循环中的陷阱(转载)
- 下一篇: 06-基于 XML 和注解 的 IOC