目錄
- Spring容器說明:
- Ioc容器優勢:
- DI介紹:
- 從Spring獲取對象:
- 獲取對象的方法:
- 關于上下文的概念:
- @Controller注解(控制層:接收參數并響應):
- @Service注解(業務邏輯層:處理業務數據):
- @Repository注解(數據層:調用數據庫用來獲取數據):
- @Configuration注解(配置層):
- @Component注解在(組件層):
- @Bean注解(方法注解):
- 上面五大注解和方法注解的區別:
- bean-->對象的命名規則:
- Spring掃描路徑:
- 什么是DI:
- DI的常用方法:
- 1.屬性注入:
- 2.構造方法注入:
- 3.set方法注入:
- @Autowired存在的問題:
- 解決措施:
- 1.加上@Qualifier注解進一步通過名稱來找bean:
- 2.加上@Primary注解:
- 3.加上@Resource注解:
- 面試題:@Resource和@Autowired的區別:
- @Autowired的裝配順序:
Spring容器說明:
Spring 就是?種IoC容器,Spring 容器 管理的主要是對象, 這些對象, 我們稱之為"Bean". 我們把這些對象交由Spring管理, 由
Spring來負責對象的創建和銷毀. 我們程序只需要告訴Spring, 哪些需要存, 以及如何從Spring中取出對象
把對象交給Spring管理,需要添加一些注解這里共有兩類注解可以使用:
1.類注解:@Controller,@Service,@Repository,@Component,@Configuration
2.方法注解:@Bean
我們接下來就主要圍繞注解的使用來講解
Ioc容器優勢:
1.控制權發生反轉:不在需要使用方,創建對象并控制依賴,不需要自己創建對象和初始化,這就是控制反轉
2.集中資源管理:
IOC容器會幫我們管理一些資源(對象)時, 只需要從IoC容器中去取
就可以了
3.降低資源的耦合度:我們在創建實例的時候不需要了解其中的細節, 降低了使用資源雙方的依賴程度
DI介紹:
DI就是注入依賴,容器在運行時動態的為程序注入所需的依賴
依賴就是程序運行時需要的一些成員屬性
從Spring獲取對象:
因為對象被交給了Spring管理,所以我們要先獲取Spring的上下文->ApplicationContext,再來根據方法獲取對象
獲取對象的方法:
這里我們主要根據名稱獲取,這個名稱是唯一的,根據類型獲取,這個類型就是某個類,根據名稱+類型獲取
// 1. 根據bean名稱獲取beanObject getBean(String var1) throws BeansException;// 2. 根據bean名稱和類型獲取bean<T> T getBean(String var1, Class<T> var2) throws BeansException;// 3. 按bean名稱和構造函數參數動態創建bean,只適?于具有原型(prototype)作?域的beanObject getBean(String var1, Object... var2) throws BeansException;// 4. 根據類型獲取bean<T> T getBean(Class<T> var1) throws BeansException;// 5. 按bean類型和構造函數參數動態創建bean, 只適?于具有原型(prototype)作?域的
bean<T> T getBean(Class<T> var1, Object... var2) throws BeansException;
關于上下文的概念:
比如線程上下文:一個棧結構,用于存儲上層線程的上下文信息,以便繼續執行。
包含當前線程的位置、設置、本地變量等信息。類似于一個環境和這里的Spring容器的上下文, 就是指當前的運行環境, 也可以看作是?個容器, 容器里存了很多內容, 這些內容是當前
運行的環境**
@Controller注解(控制層:接收參數并響應):
使用@Controller 存儲對象(bean):
import org.springframework.stereotype.Controller;@Controller
public class HelloController {public void print(){System.out.println("do Controller");}
}
用名稱獲取對象:就是把對象交給Spring容器管理
public static void main(String[] args) {//獲取Spring上下文ApplicationContext context = SpringApplication.run(SpringIocDemoApplication.class, args);HelloController bean1 = (HelloController) context.getBean("helloController");bean1.print();
用類型獲取對象:
HelloController bean2 = context.getBean(HelloController.class);bean2.print();
使用類型和名稱獲取對象:
HelloController bean3 = context.getBean("helloController",HelloController.class);bean3.print();
@Service注解(業務邏輯層:處理業務數據):
存儲對象代碼如下:
import org.springframework.stereotype.Service;@Service
public class UserService {public void print(){System.out.println("do Service");}
}
使用類型獲取對象:
UserService bean7 = context.getBean(UserService.class);bean7.print();
@Repository注解(數據層:調用數據庫用來獲取數據):
存儲對象代碼如下:
import org.springframework.stereotype.Repository;@Repository
public class UserRepository {public void print(){System.out.println("do Repository");}
}
使用類型獲取對象:
UserRepository bean6 = context.getBean(UserRepository.class);bean6.print();
@Configuration注解(配置層):
存儲對象代碼如下:
import org.springframework.context.annotation.Configuration;@Configuration("reNameBean")
public class UserConfig {public void print(){System.out.println("do config");}
}
使用類型獲取對象:
UserConfig bean4 = context.getBean(UserConfig.class);bean4.print();
@Component注解在(組件層):
存儲對象代碼如下:
import org.springframework.stereotype.Component;@Component
public class UserComponent {public void print(){System.out.println("do Component");}
}
使用類型獲取對象:
UserComponent bean8 = context.getBean(UserComponent.class);bean8.print();
@Bean注解(方法注解):
注意:方法注解使用時候注意要搭配以上的五大類注解使用:
Bean這個注解使用的場景:一個類需要多個對象:(上面的五大注解,只可以有一個對象)
以上五大注解和這個類注解都可以修改,對象的名字,就是讓Spring按照我們的名字管理
查看對象:按照修改的對象
Student bean9 = (Student) context.getBean("ss1");System.out.println(bean9);Student bean10 = (Student) context.getBean("s2");System.out.println(bean10);
上面五大注解和方法注解的區別:
除了控制層必須使用注解(@Controller)之外,其他四個注解都可以替換使用,但是一般規范來說都在各自的層級使用
控制層使用其他注解有時候可以使用成功但是不穩定不規范
注解細節:
bean–>對象的命名規則:
從Spring容器獲取對象時,通過名稱獲取就需要命名:
五大類注解:
以小駝峰命名,如果類名前兩個字母為大寫那么就是這個類名本身
bean注解:
方法注解要搭配類注解使用,命名默認為方法名
Spring掃描路徑:
Spring掃描路徑是啟動類所在路徑,的子路徑及子孫路徑一直往后掃描
修改后演示:
發現其路徑,剛開始的”HelloController“都啟動不了:
也可以通過注解手動修改啟動類路徑:@ComponentScan
什么是DI:
DI就是依賴注入,它是一個過程,就是把Spring管理的依賴就是對象,拿出來再注入到指定的屬性中
DI的常用方法:
1.屬性注入:
通過注解@Autowired來實現:
結果:
2.構造方法注入:
構造方法注入需要注意:
當有一個構造方法時,沒得選可以注入成功,但是有多個構造方法時注入由于反射機制去獲取無參數的構造方法
有多個構造方法時,由于反射機制,會去選擇無參數的構造方法導致對象沒有注入
這個時候就需要加上@Autowired注解,選中使用的構造方法:
3.set方法注入:
在set方法加上@Autowired注解就行:
@Autowired存在的問題:
@Autowired注解通過類型來找到對象,如果有多個對象,就會報錯:因為@Autowired注解首先按照類型來找對象的,找到多個對象不知道使用哪個
解決措施:
1.加上@Qualifier注解進一步通過名稱來找bean:
@Qualifier注解不能單獨使用,必須配合@Autowired使用
2.加上@Primary注解:
@Primary,沒有參數,所以使用在多個對象那一級來指定
指定:
3.加上@Resource注解:
@Resource注解:直接通過name屬性來指定要注入的bean名稱:
面試題:@Resource和@Autowired的區別:
面試官喜歡聽到的回答:按照類型來
1.@Autowird注解是Spring提高的注解,而@Resource注解是jdk提供的
2.@Resource按照名稱注入,@Autowired按照類型注入,@Resource支持更多參數設置,按照name屬性來找bean
拓展:@Resource不完全按照名稱查找,也需要在類型的基礎上按照名稱查找
@Autowired的裝配順序:
首先按照類型找bean,找不到拋異常,找到一個裝配;如果找到多個對象時按照@Qualifier查找,我們找到@Qualifier是按照名稱來找bean的,所以@Autowired準確來說是按照“類型+名稱”來注入對象的