在以前的項目中,咱們都是經過xml文件進行bean或者某些屬性的賦值,其實還有另一種註解的方式,在企業開發中使用的不少,在bean上添加註解,能夠快速的將bean註冊到ioc容器。java
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.or...
http://www.springframework.or...
http://www.springframework.or...">
<!--
若是想要將自定義的bean對象添加到IOC容器中,須要在類上添加某些註解
Spring中包含4個主要的組件添加註解:
@Controller:控制器,推薦給controller層添加此註解
@Service:業務邏輯,推薦給業務邏輯層添加此註解
@Repository:倉庫管理,推薦給數據訪問層添加此註解
@Component:給不屬於以上基層的組件添加此註解
注意:咱們雖然人爲的給不一樣的層添加不一樣的註解,可是在spring看來,能夠在任意層添加任意註解
spring底層是不會給具體的層次驗證註解,這樣寫的目的只是爲了提升可讀性,最偷懶的方式
就是給全部想交由IOC容器管理的bean對象添加component註解
使用註解須要以下步驟:
一、添加上述四個註解中的任意一個
二、添加自動掃描註解的組件,此操做須要依賴context命名空間
三、添加自動掃描的標籤context:component-scan
注意:當使用註解註冊組件和使用配置文件註冊組件是同樣的,可是要注意:
一、組件的id默認就是組件的類名首字符小寫,若是非要更名字的話,直接在註解中添加便可
二、組件默認狀況下都是單例的,若是須要配置多例模式的話,能夠在註解下添加@Scope註解
-->
<!--
定義自動掃描的基礎包:
base-package:指定掃描的基礎包,spring在啓動的時候會將基礎包及子包下全部加了註解的類都自動
掃描進IOC容器
-->
<context:component-scan base-package="com.mashibing"></context:component-scan>
</beans>spring
PersonController.java package com.mashibing.controller; import org.springframework.stereotype.Controller; @Controller public class PersonController { public PersonController() { System.out.println("建立對象"); } } PersonService.java package com.mashibing.service; import org.springframework.stereotype.Service; @Service public class PersonService { } PersonDao.java package com.mashibing.dao; import org.springframework.stereotype.Repository; @Repository("personDao") @Scope(value="prototype") public class PersonDao { }
當定義好基礎的掃描包後,在某些狀況下可能要有選擇性的配置是否要註冊bean到IOC容器中,此時能夠經過以下的方式進行配置。sql
applicationContext.xmlexpress
<?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.or...
http://www.springframework.or...
http://www.springframework.or...">
<context:component-scan base-package="com.mashibing" use-default-filters="false">
<!--
當定義好基礎掃描的包以後,能夠排除包中的某些類,使用以下的方式:
type:表示指定過濾的規則
annotation:按照註解進行排除,標註了指定註解的組件不要,expression表示要過濾的註解
assignable:指定排除某個具體的類,按照類排除,expression表示不註冊的具體類名
aspectj:後面講aop的時候說明要使用的aspectj表達式,不用
custom:定義一個typeFilter,本身寫代碼決定哪些類被過濾掉,不用
regex:使用正則表達式過濾,不用
-->
<!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
<!--指定只掃描哪些組件,默認狀況下是所有掃描的,因此此時要配置的話須要在component-scan標籤中添加 use-default-filters="false"-->
<context:include-filter type="assignable" expression="com.mashibing.service.PersonService"/>
</context:component-scan>
</beans>app
使用註解的方式實現自動注入須要使用@AutoWired註解。框架
PersonController.java package com.mashibing.controller; import com.mashibing.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("建立對象"); } public void getPerson(){ personService.getPerson(); } } PersonService.java package com.mashibing.service; import com.mashibing.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.mashibing.dao; import org.springframework.stereotype.Repository; @Repository public class PersonDao { public void getPerson(){ System.out.println("PersonDao:getPerson"); } }
注意:當使用AutoWired註解的時候,自動裝配的時候是根據類型實現的。學習
一、若是隻找到一個,則直接進行賦值,prototype
二、若是沒有找到,則直接拋出異常,code
三、若是找到多個,那麼會按照變量名做爲id繼續匹配,
一、匹配上直接進行裝配
二、若是匹配不上則直接報異常
PersonServiceExt.java package com.mashibing.service; import com.mashibing.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.mashibing.controller; import com.mashibing.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("建立對象"); } public void getPerson(){ personServiceExt.getPerson(); } }
還可使用@Qualifier註解來指定id的名稱,讓spring不要使用變量名,當使用@Qualifier註解的時候也會有兩種狀況:
一、找到,則直接裝配
二、找不到,就會報錯
PersonController.java package com.mashibing.controller; import com.mashibing.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("建立對象"); } public void getPerson(){ personServiceExt2.getPerson(); } }
經過上述的代碼咱們可以發現,使用@AutoWired確定是可以裝配上的,若是裝配不上就會報錯。
當咱們查看@AutoWired註解的源碼的時候發現,此註解不只可使用在成員變量上,也可使用在方法上。
PersonController.java package com.mashibing.controller; import com.mashibing.dao.PersonDao; import com.mashibing.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("建立對象"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); // personServiceExt2.getPerson(); } /** * 當方法上有@AutoWired註解時: * 一、此方法在bean建立的時候會自動調用 * 二、這個方法的每個參數都會自動注入值 * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("此方法被調用:"+personDao); } /** * @Qualifier註解也能夠做用在屬性上,用來被看成id去匹配容器中的對象,若是沒有 * 此註解,那麼直接按照類型進行匹配 * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("此方法被調用:"+personService); } }
在使用自動裝配的時候,出了可使用@AutoWired註解以外,還可使用@Resource註解,你們須要知道這兩個註解的區別。
一、@AutoWired:是spring中提供的註解,@Resource:是jdk中定義的註解,依靠的是java的標準
二、@AutoWired默認是按照類型進行裝配,默認狀況下要求依賴的對象必須存在,@Resource默認是按照名字進行匹配的,同時能夠指定name屬性。
三、@AutoWired只適合spring框架,而@Resource擴展性更好
PersonController.java package com.mashibing.controller; import com.mashibing.dao.PersonDao; import com.mashibing.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("建立對象"); } public void getPerson(){ System.out.println("personController..."+personServiceExt2); personServiceExt2.getPerson(); } /** * 當方法上有@AutoWired註解時: * 一、此方法在bean建立的時候會自動調用 * 二、這個方法的每個參數都會自動注入值 * @param personDao */ @Autowired public void test(PersonDao personDao){ System.out.println("此方法被調用:"+personDao); } /** * @Qualifier註解也能夠做用在屬性上,用來被看成id去匹配容器中的對象,若是沒有 * 此註解,那麼直接按照類型進行匹配 * @param personService */ @Autowired public void test2(@Qualifier("personServiceExt") PersonService personService){ System.out.println("此方法被調用:"+personService); } }
爲了講解泛型依賴注入,首先咱們須要先寫一個基本的案例,按照咱們以前學習的知識:
Student.java package com.mashibing.bean; public class Student { } Teacher.java package com.mashibing.bean; public class Teacher { } BaseDao.java package com.mashibing.dao; import org.springframework.stereotype.Repository; @Repository public abstract class BaseDao<T> { public abstract void save(); } StudentDao.java package com.mashibing.dao; import com.mashibing.bean.Student; import org.springframework.stereotype.Repository; @Repository public class StudentDao extends BaseDao<Student>{ public void save() { System.out.println("保存學生"); } } TeacherDao.java package com.mashibing.dao; import com.mashibing.bean.Teacher; import org.springframework.stereotype.Repository; @Repository public class TeacherDao extends BaseDao<Teacher> { public void save() { System.out.println("保存老師"); } } StudentService.java package com.mashibing.service; import com.mashibing.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.mashibing.service; import com.mashibing.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.mashibing.service.StudentService; import com.mashibing.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(); } }
上述代碼是咱們以前的能夠完成的功能,可是能夠思考,Service層的代碼是否可以改寫:
BaseService.java package com.mashibing.service; import com.mashibing.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.mashibing.service; import com.mashibing.bean.Student; import com.mashibing.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.mashibing.service; import com.mashibing.bean.Teacher; import com.mashibing.dao.TeacherDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TeacherService extends BaseService<Teacher>{ }