03-Spring IOC容器的基本使用(註解的使用)
03SpringIOC的註解應用
在之前的專案中,我們都是通過xml檔案進行bean或者某些屬性的賦值,其實還有另外一種註解的方式,在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">
<!--
如果想要將自定義的bean物件新增到IOC容器中,需要在類上新增某些註解
Spring中包含4個主要的元件新增註解:
@Controller:控制器,推薦給controller層新增此註解
@Service:業務邏輯,推薦給業務邏輯層新增此註解
@Repository:倉庫管理,推薦給資料訪問層新增此註解
@Component:給不屬於以上基層的元件新增此註解
注意:我們雖然人為的給不同的層新增不同的註解,但是在spring看來,可以在任意層新增任意註解
spring底層是不會給具體的層次驗證註解,這樣寫的目的只是為了提高可讀性,最偷懶的方式
就是給所有想交由IOC容器管理的bean物件新增component註解
使用註解需要如下步驟:
1、新增上述四個註解中的任意一個
2、新增自動掃描註解的元件,此操作需要依賴context名稱空間
3、新增自動掃描的標籤context:component-scan
注意:當使用註解註冊元件和使用配置檔案註冊元件是一樣的,但是要注意:
1、元件的id預設就是元件的類名首字元小寫,如果非要改名字的話,直接在註解中新增即可
2、元件預設情況下都是單例的,如果需要配置多例模式的話,可以在註解下新增@Scope註解
-->
<!--
定義自動掃描的基礎包:
base-package:指定掃描的基礎包,spring在啟動的時候會將基礎包及子包下所有加了註解的類都自動
掃描進IOC容器
-->
<context:component-scan base-package="com.mashibing"></context:component-scan>
</beans>
PersonController.java
@Controller
public class PersonController {
public PersonController() {
System.out.println("建立物件");
}
}
PersonService.java
@Service
public class PersonService {
}
PersonDao.java
@Repository("personDao")
@Scope(value="prototype")// 配置為多例模式
public class PersonDao {
}
2、定義掃描包時要包含的類和不要包含的類
當定義好基礎的掃描包後,在某些情況下可能要有選擇性的配置是否要註冊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">
<context:component-scan base-package="com.wwl" 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>
3、使用@AutoWired進行自動注入
使用註解的方式實現自動注入需要使用@AutoWired註解。
PersonController.java
@Controller
public class PersonController {
@Autowired
private PersonService personService;
public PersonController() {
System.out.println("建立物件");
}
public void getPerson(){
personService.getPerson();
}
}
PersonService.java
@Service
public class PersonService {
@Autowired
private PersonDao personDao;
public void getPerson(){
personDao.getPerson();
}
}
PersonDao.java
@Repository
public class PersonDao {
public void getPerson(){
System.out.println("PersonDao:getPerson");
}
}
注意:當使用AutoWired註解的時候,自動裝配的時候是根據型別實現的。
1、如果只找到一個,則直接進行賦值,
2、如果沒有找到,則直接丟擲異常,
3、如果找到多個,那麼會按照變數名作為id繼續匹配,
1、匹配上直接進行裝配
2、如果匹配不上則直接報異常
PersonServiceExt.java
@Service
public class PersonServiceExt extends PersonService{
@Autowired
private PersonDao personDao;
public void getPerson(){
System.out.println("PersonServiceExt......");
personDao.getPerson();
}
}
PersonController.java
@Controller
public class PersonController {
@Autowired
private PersonService personServiceExt;
public PersonController() {
System.out.println("建立物件");
}
public void getPerson(){
personServiceExt.getPerson();
}
}
還可以使用@Qualifier註解來指定id的名稱,讓spring不要使用變數名,當使用@Qualifier註解的時候也會有兩種情況:
1、找到,則直接裝配
2、找不到,就會報錯
PersonController.java
@Controller
public class PersonController {
@Autowired
@Qualifier("personService")
private PersonService personServiceExt2;
public PersonController() {
System.out.println("建立物件");
}
public void getPerson(){
personServiceExt2.getPerson();
}
}
通過上述的程式碼我們能夠發現,使用@AutoWired肯定是能夠裝配上的,如果裝配不上就會報錯。
4、@AutoWired可以進行定義在方法上
當我們檢視@AutoWired註解的原始碼的時候發現,此註解不僅可以使用在成員變數上,也可以使用在方法上。
PersonController.java
@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註解時:
* 1、此方法在bean建立的時候會自動呼叫
* 2、這個方法的每一個引數都會自動注入值
* @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);
}
}
5、自動裝配的註解@AutoWired,@Resource
在使用自動裝配的時候,出了可以使用@AutoWired註解之外,還可以使用@Resource註解,大家需要知道這兩個註解的區別。
1、@AutoWired:是spring中提供的註解,@Resource:是jdk中定義的註解,依靠的是java的標準
2、@AutoWired預設是按照型別進行裝配,預設情況下要求依賴的物件必須存在,@Resource預設是按照名字進行匹配的,同時可以指定name屬性。
3、@AutoWired只適合spring框架,而@Resource擴充套件性更好
PersonController.java
@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註解時:
* 1、此方法在bean建立的時候會自動呼叫
* 2、這個方法的每一個引數都會自動注入值
* @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);
}
}
6、泛型依賴注入
為了講解泛型依賴注入,首先我們需要先寫一個基本的案例,按照我們之前學習的知識:
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>{
}
相關文章
- Spring IOC 常用註解與使用Spring
- 2、Spring使用+ioc容器配置使用1Spring
- 3註釋的基本使用
- 【Spring】IOC容器註解彙總,你想要的都在這兒了!!Spring
- lombok幾個基本註解的使用@Data@AllArgsConstructor@NoArgsConstructorLombokStruct
- 註解@PropertySource的使用
- Java註解的使用Java
- @responseBody註解的使用
- @Mapper註解的使用APP
- lombok幾個基本註解的使用@Data@AllArgsConstructor@NoArgsConstructor@BuilderLombokStructUI
- spring原始碼深度解析— IOC 之 容器的基本實現Spring原始碼
- Spring的IOC容器Spring
- Laravel的Ioc容器Laravel
- 使用 IoC 容器進行程式碼優化行程優化
- Spring基於註解的IoC配置Spring
- Docker掃盲之容器與映象的基本使用Docker
- Spring的@PropertySource註解使用Spring
- java中的註解使用Java
- Spring5原始碼解析_IOC之容器的基本實現Spring原始碼
- Spring的IOC常用註解(含原始碼)Spring原始碼
- 詳解 PHP 反射的基本使用PHP反射
- @GrpcServise 註解的作用和使用RPC
- 如何使用JPA的@Formula註解?ORM
- Spring管理的@Configuration註解使用Spring
- Spring MVC 常用註解的使用SpringMVC
- Spring中@Import註解的使用SpringImport
- Java註解與反射的使用Java反射
- springBoot自定義註解的使用Spring Boot
- myBatis——註解,#{}與${},resultMap的使用MyBatis
- 【Spring註解驅動開發】在@Import註解中使用ImportBeanDefinitionRegistrar向容器中註冊beanSpringImportBean
- 【Spring註解開發】元件註冊-使用@Configuration和@Bean給容器中註冊元件Spring元件Bean
- 如何向Spring IOC 容器 動態註冊beanSpringBean
- Spring IoC 公共註解詳解Spring
- 淺析 Spring 的IOC容器Spring
- 對Spring IOC容器的思考Spring
- Java 如何優雅的使用註解Java
- AspectJ 使用的一些註解
- Spring的@Qualifier註解使用說明Spring