SpringIOC的注解應(yīng)用方式
? 在之前的項目中,我們都是通過xml文件進(jìn)行bean或者某些屬性的賦值,其實還有另外一種注解的方式,在企業(yè)開發(fā)中使用的很多,在bean上添加注解,可以快速的將bean注冊到ioc容器。
1、使用注解的方式注冊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、添加上述四個注解中的任意一個 2、添加自動掃描注解的組件,此操作需要依賴context命名空間 3、添加自動掃描的標(biāo)簽context:component-scan 注意:當(dāng)使用注解注冊組件和使用配置文件注冊組件是一樣的,但是要注意: 1、組件的id默認(rèn)就是組件的類名首字符小寫,如果非要改名字的話,直接在注解中添加即可 2、組件默認(rèn)情況下都是單例的,如果需要配置多例模式的話,可以在注解下添加@Scope注解 --> <!-- 定義自動掃描的基礎(chǔ)包: base-package:指定掃描的基礎(chǔ)包,spring在啟動的時候會將基礎(chǔ)包及子包下所有加了注解的類都自動 掃描進(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)建對象"); } }
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對象添加到IOC容器中,需要在類上添加某些注解
Spring中包含4個主要的組件添加注解:
- @Controller:控制器,推薦給controller層添加此注解
- @Service:業(yè)務(wù)邏輯,推薦給業(yè)務(wù)邏輯層添加此注解
- @Repository:倉庫管理,推薦給數(shù)據(jù)訪問層添加此注解
- @Component:給不屬于以上基層的組件添加此注解
注意:我們雖然人為的給不同的層添加不同的注解,但是在spring看來,可以在任意層添加任意注解,但spring底層是不會給具體的層次驗證注解,這樣寫的目的只是為了提高可讀性,最偷懶的方式就是給所有想交由IOC容器管理的bean對象添加component注解
2、定義掃描包時要包含的類和不要包含的類
? 當(dāng)定義好基礎(chǔ)的掃描包后,在某些情況下可能要有選擇性的配置是否要注冊bean到IOC容器中,此時可以通過如下的方式進(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ī)則 annotation:按照注解進(jìn)行排除,標(biāo)注了指定注解的組件不要,expression表示要過濾的注解 assignable:指定排除某個具體的類,按照類排除,expression表示不注冊的具體類名 aspectj:aop使用的aspectj表達(dá)式,一般不用 custom:定義一個typeFilter,自己寫代碼決定哪些類被過濾掉,一般不用 regex:使用正則表達(dá)式過濾,一般不用 --> <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--> <!--指定只掃描哪些組件,默認(rèn)情況下是全部掃描的,所以此時要配置的話需要在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)行自動注入
? 使用注解的方式實現(xiàn)自動注入需要使用@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)建對象"); } 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注解的時候,自動裝配的時候是根據(jù)類型實現(xiàn)的。
? 1、如果只找到一個,則直接進(jìn)行賦值,
? 2、如果沒有找到,則直接拋出異常,
? 3、如果找到多個,那么會按照變量名作為id繼續(xù)匹配,
- 匹配上直接進(jìn)行裝配
- 如果匹配不上則直接報異常
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)建對象"); } public void getPerson(){ personServiceExt.getPerson(); } }
? 還可以使用@Qualifier注解來指定id的名稱,讓spring不要使用變量名,當(dāng)使用@Qualifier注解的時候也會有兩種情況:
? 1、找到,則直接裝配
? 2、找不到,就會報錯
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)建對象"); } public void getPerson(){ personServiceExt2.getPerson(); } }
? 通過上述的代碼我們能夠發(fā)現(xiàn),使用@AutoWired肯定是能夠裝配上的,如果裝配不上就會報錯。
4、@AutoWired可以進(jìn)行定義在方法上
? 當(dāng)我們查看@AutoWired注解的源碼的時候發(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)建對象"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); // personServiceExt2.getPerson(); } /** * 當(dāng)方法上有@AutoWired注解時: * 1、此方法在bean創(chuàng)建的時候會自動調(diào)用 * 2、這個方法的每一個參數(shù)都會自動注入值 * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("此方法被調(diào)用:"+personDao); } /** * @Qualifier注解也可以作用在屬性上,用來被當(dāng)作id去匹配容器中的對象,如果沒有 * 此注解,那么直接按照類型進(jìn)行匹配 * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("此方法被調(diào)用:"+personService); } }
5、自動裝配的注解@AutoWired,@Resource
? 在使用自動裝配的時候,出了可以使用@AutoWired注解之外,還可以使用@Resource注解。
? 1、@AutoWired:是spring中提供的注解,@Resource:是jdk中定義的注解,依靠的是java的標(biāo)準(zhǔn)
? 2、@AutoWired默認(rèn)是按照類型進(jìn)行裝配,默認(rèn)情況下要求依賴的對象必須存在,@Resource默認(rèn)是按照名字進(jìn)行匹配的,同時可以指定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)建對象"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); personServiceExt2.getPerson(); } /** * 當(dāng)方法上有@AutoWired注解時: * 1、此方法在bean創(chuàng)建的時候會自動調(diào)用 * 2、這個方法的每一個參數(shù)都會自動注入值 * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("此方法被調(diào)用:"+personDao); } /** * @Qualifier注解也可以作用在屬性上,用來被當(dāng)作id去匹配容器中的對象,如果沒有 * 此注解,那么直接按照類型進(jìn)行匹配 * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("此方法被調(diào)用:"+personService); } }
6、泛型依賴注入
? 為了了解泛型依賴注入,首先我們需要先寫一個基本的案例:
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(); } }
? 上述代碼可以完成對應(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("自動注入的對象:"+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é)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請求的操作
這篇文章主要介紹了解決Spring Cloud Gateway獲取body內(nèi)容,不影響GET請求的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12java 將jsonarray 轉(zhuǎn)化為對應(yīng)鍵值的jsonobject方法
下面小編就為大家分享一篇java 將jsonarray 轉(zhuǎn)化為對應(yīng)鍵值的jsonobject方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03舉例分析Python中設(shè)計模式之外觀模式的運(yùn)用
這篇文章主要介紹了Python中設(shè)計模式之外觀模式的運(yùn)用,外觀模式主張以分多模塊進(jìn)行代碼管理而減少耦合,需要的朋友可以參考下2016-03-03javaweb學(xué)習(xí)總結(jié)——使用JDBC處理MySQL大數(shù)據(jù)
本篇文章主要介紹了JDBC處理MySQL大數(shù)據(jù),有時是需要用程序把大文本或二進(jìn)制數(shù)據(jù)直接保存到數(shù)據(jù)庫中進(jìn)行儲存的,非常具有實用價值,需要的朋友可以參考下。2016-11-11