SpringIOC的注解應(yīng)用方式
? 在之前的項(xiàng)目中,我們都是通過(guò)xml文件進(jìn)行bean或者某些屬性的賦值,其實(shí)還有另外一種注解的方式,在企業(yè)開發(fā)中使用的很多,在bean上添加注解,可以快速的將bean注冊(cè)到ioc容器。
1、使用注解的方式注冊(cè)bean到IOC容器中
applicationContext.xml
<?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"> <!-- 使用注解需要如下步驟: 1、添加上述四個(gè)注解中的任意一個(gè) 2、添加自動(dòng)掃描注解的組件,此操作需要依賴context命名空間 3、添加自動(dòng)掃描的標(biāo)簽context:component-scan 注意:當(dāng)使用注解注冊(cè)組件和使用配置文件注冊(cè)組件是一樣的,但是要注意: 1、組件的id默認(rèn)就是組件的類名首字符小寫,如果非要改名字的話,直接在注解中添加即可 2、組件默認(rèn)情況下都是單例的,如果需要配置多例模式的話,可以在注解下添加@Scope注解 --> <!-- 定義自動(dòng)掃描的基礎(chǔ)包: base-package:指定掃描的基礎(chǔ)包,spring在啟動(dòng)的時(shí)候會(huì)將基礎(chǔ)包及子包下所有加了注解的類都自動(dòng) 掃描進(jìn)IOC容器 --> <context:component-scan base-package="com.example"></context:component-scan> </beans>
PersonController.java
package com.example.controller; import org.springframework.stereotype.Controller; @Controller public class PersonController { public PersonController() { System.out.println("創(chuàng)建對(duì)象"); } }
PersonService.java
package com.exxample.service; import org.springframework.stereotype.Service; @Service public class PersonService { }
PersonDao.java
package com.example.dao; import org.springframework.stereotype.Repository; @Repository("personDao") @Scope(value="prototype")//默認(rèn)singleton,改為prototype public class PersonDao { }
如果想要將自定義的bean對(duì)象添加到IOC容器中,需要在類上添加某些注解
Spring中包含4個(gè)主要的組件添加注解:
- @Controller:控制器,推薦給controller層添加此注解
- @Service:業(yè)務(wù)邏輯,推薦給業(yè)務(wù)邏輯層添加此注解
- @Repository:倉(cāng)庫(kù)管理,推薦給數(shù)據(jù)訪問(wèn)層添加此注解
- @Component:給不屬于以上基層的組件添加此注解
注意:我們雖然人為的給不同的層添加不同的注解,但是在spring看來(lái),可以在任意層添加任意注解,但spring底層是不會(huì)給具體的層次驗(yàn)證注解,這樣寫的目的只是為了提高可讀性,最偷懶的方式就是給所有想交由IOC容器管理的bean對(duì)象添加component注解
2、定義掃描包時(shí)要包含的類和不要包含的類
? 當(dāng)定義好基礎(chǔ)的掃描包后,在某些情況下可能要有選擇性的配置是否要注冊(cè)bean到IOC容器中,此時(shí)可以通過(guò)如下的方式進(jìn)行配置。
applicationContext.xml
<?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"> <context:component-scan base-package="com.example" use-default-filters="false"> <!-- 當(dāng)定義好基礎(chǔ)掃描的包之后,可以排除包中的某些類,使用如下的方式: type:表示指定過(guò)濾的規(guī)則 annotation:按照注解進(jìn)行排除,標(biāo)注了指定注解的組件不要,expression表示要過(guò)濾的注解 assignable:指定排除某個(gè)具體的類,按照類排除,expression表示不注冊(cè)的具體類名 aspectj:aop使用的aspectj表達(dá)式,一般不用 custom:定義一個(gè)typeFilter,自己寫代碼決定哪些類被過(guò)濾掉,一般不用 regex:使用正則表達(dá)式過(guò)濾,一般不用 --> <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--> <!--指定只掃描哪些組件,默認(rèn)情況下是全部掃描的,所以此時(shí)要配置的話需要在component-scan標(biāo)簽中添加 use-default-filters="false"--> <context:include-filter type="assignable" expression="com.example.service.PersonService"/> </context:component-scan> </beans>
3、使用@AutoWired進(jìn)行自動(dòng)注入
? 使用注解的方式實(shí)現(xiàn)自動(dòng)注入需要使用@AutoWired注解。
PersonController.java
package com.example.controller; import com.example.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired private PersonService personService; public PersonController() { System.out.println("創(chuàng)建對(duì)象"); } public void getPerson(){ personService.getPerson(); } }
PersonService.java
package com.example.service; import com.example.dao.PersonDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PersonService { @Autowired private PersonDao personDao; public void getPerson(){ personDao.getPerson(); } }
PersonDao.java
package com.example.dao; import org.springframework.stereotype.Repository; @Repository public class PersonDao { public void getPerson(){ System.out.println("PersonDao:getPerson"); } }
注意:當(dāng)使用AutoWired注解的時(shí)候,自動(dòng)裝配的時(shí)候是根據(jù)類型實(shí)現(xiàn)的。
? 1、如果只找到一個(gè),則直接進(jìn)行賦值,
? 2、如果沒(méi)有找到,則直接拋出異常,
? 3、如果找到多個(gè),那么會(huì)按照變量名作為id繼續(xù)匹配,
- 匹配上直接進(jìn)行裝配
- 如果匹配不上則直接報(bào)異常
PersonServiceExt.java
package com.example.service; import com.example.dao.PersonDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class PersonServiceExt extends PersonService{ @Autowired private PersonDao personDao; public void getPerson(){ System.out.println("PersonServiceExt......"); personDao.getPerson(); } }
PersonController.java
package com.example.controller; import com.example.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired private PersonService personServiceExt; public PersonController() { System.out.println("創(chuàng)建對(duì)象"); } public void getPerson(){ personServiceExt.getPerson(); } }
? 還可以使用@Qualifier注解來(lái)指定id的名稱,讓spring不要使用變量名,當(dāng)使用@Qualifier注解的時(shí)候也會(huì)有兩種情況:
? 1、找到,則直接裝配
? 2、找不到,就會(huì)報(bào)錯(cuò)
PersonController.java
package com.example.controller; import com.example.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Autowired @Qualifier("personService") private PersonService personServiceExt2; public PersonController() { System.out.println("創(chuàng)建對(duì)象"); } public void getPerson(){ personServiceExt2.getPerson(); } }
? 通過(guò)上述的代碼我們能夠發(fā)現(xiàn),使用@AutoWired肯定是能夠裝配上的,如果裝配不上就會(huì)報(bào)錯(cuò)。
4、@AutoWired可以進(jìn)行定義在方法上
? 當(dāng)我們查看@AutoWired注解的源碼的時(shí)候發(fā)現(xiàn),此注解不僅可以使用在成員變量上,也可以使用在方法上。
PersonController.java
package com.example.controller; import com.example.dao.PersonDao; import com.example.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; @Controller public class PersonController { @Qualifier("personService") @Autowired private PersonService personServiceExt2; public PersonController() { System.out.println("創(chuàng)建對(duì)象"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); // personServiceExt2.getPerson(); } /** * 當(dāng)方法上有@AutoWired注解時(shí): * 1、此方法在bean創(chuàng)建的時(shí)候會(huì)自動(dòng)調(diào)用 * 2、這個(gè)方法的每一個(gè)參數(shù)都會(huì)自動(dòng)注入值 * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("此方法被調(diào)用:"+personDao); } /** * @Qualifier注解也可以作用在屬性上,用來(lái)被當(dāng)作id去匹配容器中的對(duì)象,如果沒(méi)有 * 此注解,那么直接按照類型進(jìn)行匹配 * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("此方法被調(diào)用:"+personService); } }
5、自動(dòng)裝配的注解@AutoWired,@Resource
? 在使用自動(dòng)裝配的時(shí)候,出了可以使用@AutoWired注解之外,還可以使用@Resource注解。
? 1、@AutoWired:是spring中提供的注解,@Resource:是jdk中定義的注解,依靠的是java的標(biāo)準(zhǔn)
? 2、@AutoWired默認(rèn)是按照類型進(jìn)行裝配,默認(rèn)情況下要求依賴的對(duì)象必須存在,@Resource默認(rèn)是按照名字進(jìn)行匹配的,同時(shí)可以指定name屬性。
? 3、@AutoWired只適合spring框架,而@Resource擴(kuò)展性更好
PersonController.java
package com.example.controller; import com.example.dao.PersonDao; import com.example.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import javax.annotation.Resource; @Controller public class PersonController { @Qualifier("personService") @Resource private PersonService personServiceExt2; public PersonController() { System.out.println("創(chuàng)建對(duì)象"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); personServiceExt2.getPerson(); } /** * 當(dāng)方法上有@AutoWired注解時(shí): * 1、此方法在bean創(chuàng)建的時(shí)候會(huì)自動(dòng)調(diào)用 * 2、這個(gè)方法的每一個(gè)參數(shù)都會(huì)自動(dòng)注入值 * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("此方法被調(diào)用:"+personDao); } /** * @Qualifier注解也可以作用在屬性上,用來(lái)被當(dāng)作id去匹配容器中的對(duì)象,如果沒(méi)有 * 此注解,那么直接按照類型進(jìn)行匹配 * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("此方法被調(diào)用:"+personService); } }
6、泛型依賴注入
? 為了了解泛型依賴注入,首先我們需要先寫一個(gè)基本的案例:
Student.java
package com.example.bean; public class Student { }
Teacher.java
package com.example.bean; public class Teacher { }
BaseDao.java
package com.example.dao; import org.springframework.stereotype.Repository; @Repository public abstract class BaseDao<T> { public abstract void save(); }
StudentDao.java
package com.example.dao; import com.example.bean.Student; import org.springframework.stereotype.Repository; @Repository public class StudentDao extends BaseDao<Student>{ public void save() { System.out.println("保存學(xué)生"); } }
TeacherDao.java
package com.example.dao; import com.example.bean.Teacher; import org.springframework.stereotype.Repository; @Repository public class TeacherDao extends BaseDao<Teacher> { public void save() { System.out.println("保存老師"); } }
StudentService.java
package com.example.service; import com.example.dao.StudentDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class StudentService { @Autowired private StudentDao studentDao; public void save(){ studentDao.save(); } }
TeacherService.java
package com.example.service; import com.example.dao.TeacherDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TeacherService { @Autowired private TeacherDao teacherDao; public void save(){ teacherDao.save(); } }
MyTest.java
import com.example.service.StudentService; import com.example.service.TeacherService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.sql.DataSource; import java.sql.SQLException; public class MyTest { public static void main(String[] args) throws SQLException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); StudentService studentService = context.getBean("studentService",StudentService.class); studentService.save(); TeacherService teacherService = context.getBean("teacherService",TeacherService.class); teacherService.save(); } }
? 上述代碼可以完成對(duì)應(yīng)的功能,但是Service層的代碼能夠改寫成:
BaseService.java
package com.example.service; import com.example.dao.BaseDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; public class BaseService<T> { @Autowired BaseDao<T> baseDao; public void save(){ System.out.println("自動(dòng)注入的對(duì)象:"+baseDao); baseDao.save(); } }
StudentService.java
package com.example.service; import com.example.bean.Student; import com.example.dao.StudentDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class StudentService extends BaseService<Student> { }
TeacherService.java
package com.example.service; import com.example.bean.Teacher; import com.example.dao.TeacherDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TeacherService extends BaseService<Teacher>{ }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請(qǐng)求的操作
這篇文章主要介紹了解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請(qǐng)求的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Java中ArrayList實(shí)現(xiàn)原理及基本方法
這篇文章主要介紹了Java中ArrayList實(shí)現(xiàn)原理及基本方法,ArrayList是開發(fā)中非常常用的數(shù)據(jù)存儲(chǔ)容器之一,其底層是數(shù)組實(shí)現(xiàn)的,我們可以在集合中存儲(chǔ)任意類型的數(shù)據(jù),ArrayList是線程不安全的,擅長(zhǎng)隨機(jī)訪問(wèn)元素,插入和刪除較慢,需要的朋友可以參考下2023-08-08java開發(fā)環(huán)境的完整搭建過(guò)程
這篇文章主要給大家介紹了關(guān)于java開發(fā)環(huán)境的完整搭建過(guò)程,文中介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02java 將jsonarray 轉(zhuǎn)化為對(duì)應(yīng)鍵值的jsonobject方法
下面小編就為大家分享一篇java 將jsonarray 轉(zhuǎn)化為對(duì)應(yīng)鍵值的jsonobject方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03舉例分析Python中設(shè)計(jì)模式之外觀模式的運(yùn)用
這篇文章主要介紹了Python中設(shè)計(jì)模式之外觀模式的運(yùn)用,外觀模式主張以分多模塊進(jìn)行代碼管理而減少耦合,需要的朋友可以參考下2016-03-03javaweb學(xué)習(xí)總結(jié)——使用JDBC處理MySQL大數(shù)據(jù)
本篇文章主要介紹了JDBC處理MySQL大數(shù)據(jù),有時(shí)是需要用程序把大文本或二進(jìn)制數(shù)據(jù)直接保存到數(shù)據(jù)庫(kù)中進(jìn)行儲(chǔ)存的,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2016-11-11