網站首頁 編程語言 正文
文章目錄
- 獲取 Spring 上下文對象的方式
- 存儲 Bean 對象的方式
- 類注解
- 配置掃描路徑(必須)
- @Controller(控制器存儲)
- @Service(服務)
- @Repository(持久層)
- @Component(工具)
- @Configuration(項目中的一些配置)
- 關于五大類注解
- 方法注解
- 獲取指定的 Bean 對象的方式
- 普通方式
- 對象注入
- 屬性注入
- 構造方法注入
- Setter 注入
- @Resource:另?種注入關鍵字
- 總結
獲取 Spring 上下文對象的方式
首先獲取 Bean 對象之前都需要先獲取 Spring 的上下文對象,那么獲取這個對象可以有以下方式
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
那么這兩者之間有什么區別呢,現在新建兩個 Bean 類運行起來后看結果:
1、ApplicationContext
2、BeanFactory
兩者的運行結果是不一樣的,通過 BeanFactory 實例出來的并不會將 Teacher 對象放入 Spring
ApplicationContext 和 BeanFeactory:
- ApplicationContext 會將 xml文件中所聲明需要注冊到Spring中的 Bean 一次性全部注冊完成,而BeanFactory 則是在首次去獲取某一個Bean 對象時才會去注冊該對象
- ApplicationContext 比較廢內存但是之后的讀取會很快
- BeanFeactory 比較省內存但是效率較低
- ApplicationContext 是 BeanFeactory 的子類,ApplicationContext 還擁有獨特的特性, 添加了對國際化支持、資源訪問支持、以及事件傳播等方面的支持
存儲 Bean 對象的方式
基本的存儲方式需要在 spring-config.xml 文件中去添加指定的 Bean 注冊內容才行,這樣就很麻煩。
類注解
配置掃描路徑(必須)
首先在進行注解前需要先配置好路徑,在 spring-config.xml 中添加下面的代碼
<content:component-scan base-package="spring.demo"></content:component-scan>
base-package中添加的是一串路徑,也就是聲明這個路徑下的包中的 Bean 是有可能需要存入到 Spring 中的。注意只是有可能,開始的時候并沒有立即注冊存放到 Spring 中。
@Controller(控制器存儲)
驗證用戶請求的數據正確性,相當于“安保系統”
Student類
import org.springframework.stereotype.Controller;
@Controller // 將當前類存儲到 Spring 中
public class Student {
public Student(){
System.out.println("Student init");
}
public void print(String str){
System.out.println(str);
}
}
啟動類
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.demo.Student;
public class Start {
public static void main(String[] args) {
// 獲取 Spring 的上下文對象
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
Student student = (Student) context.getBean("student", Student.class);
// 使用 Bean 對象
student.print("hello world");
}
}
因為使用了注解后并沒有指定id屬性,這時需要將id屬性寫為類名的小駝峰形式,這是一個“約定”。
但是也有特例:
? 原類名如果首字母和第二個字母都是大寫的話,id屬性的名稱就和原類名相同
@Service(服務)
編排和調度具體執行方法,相當于“客服中心”
Student類
@Service // 將當前類存儲到 Spring 中
public class Student {
public Student(){
System.out.println("Student init");
}
public void print(String str){
System.out.println(str);
}
}
這樣也同樣可以執行程序
@Repository(持久層)
和數據庫進行交互,是一個“執行者”(DAO)
Student類
@Repository // 將當前類存儲到 Spring 中
public class Student {
public Student(){
System.out.println("Student init");
}
public void print(String str){
System.out.println(str);
}
}
這樣也同樣可以執行程序
@Component(工具)
主要是注解工具類
Student類
@Component // 將當前類存儲到 Spring 中
public class Student {
public Student(){
System.out.println("Student init");
}
public void print(String str){
System.out.println(str);
}
}
這樣也同樣可以執行程序
@Configuration(項目中的一些配置)
Student類
@Configuration // 將當前類存儲到 Spring 中
public class Student {
public Student(){
System.out.println("Student init");
}
public void print(String str){
System.out.println(str);
}
}
這樣也同樣可以執行程序
關于五大類注解
- 如果遇到同一個包中有 同名的類 那么可以在使用注解時使用例如 @Controller(value = “XXX”) 這種方式去分別,但是建議一個包中盡量不要有同名類
- 五大注解的關系:事實上五大注解都是基于 Component 實現的,也就是它們都是 Component 的“子類”,是對于 Component 的擴展。那么需要分出這么多類注解的原因就是讓程序員看到類注解之后,就能直接了解當前類的用途
方法注解
方法注解就是在一個有返回值的方法上加上 @Bean 注解的方式,也就是說 Spring 會將有著 @Bean 注解的方法的返回值的對象存入
需要注意:
- @Bean 注解需要配合五大類注解使用
- 使用了@Bean 注解后,默認的 Bean 對象ID屬性為該具有 @Bean 注解的方法名
- 可以使用 @Bean(name = {“XXX”})的形式去設置這個 Bean 對象的ID屬性。并且這個重命名的 name 其實是?個數組,一個 Bean 可以有多個名字,例如 @Bean(name = {“XXX”, “XXX”})。并且 name= 是可以去掉的,例如 @Bean({“XXX”, “XXX”})
@Component
public class UserBeans {
@Bean({"user"})
public User getUser(){
User user = new User();
user.setId(1);
user.setName("張三");
return user;
}
}
public class Start {
public static void main(String[] args) {
// 獲取 Spring 的上下文對象
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
User user = context.getBean("user", User.class);
// 使用 Bean 對象
System.out.println(user.getName());
}
}
獲取指定的 Bean 對象的方式
獲取到上下文對象之后就可以通過調用該對象的 getBean方法去獲取 Bean 對象
普通方式
首先常規的就是使用加載時設置的 id 屬性去獲取
Student student = (Student) context.getBean("student");
需要注意這種方式的返回值是 Object 類的,因此需要強轉為 Bean 對象的類
第二種方式可以通過 Bean類的.class 加上 id 屬性去獲取
Student student = context.getBean("student", Student.class);
這樣寫法就比較優美
第三種方式可以直接通過 .class去獲取,但是存在隱患
Student student = context.getBean(Student.class);
存在什么隱患呢,首先一個 Bean類是可以存放多個對象到 Spring 中的,也就是可以這樣
<bean id="student" class="spring.demo.Student"></bean> <bean id="student2" class="spring.demo.Student"></bean>
那么如果還使用第三種方式就會出現,編譯器不知道具體是要獲取哪一個對象,就會報錯
因此不建議使用這種方式
對象注入
在 Spring 中實現依賴注入的常見方式有以下 3 種:
- 屬性注入(Field Injection);
- 構造方法注入(Constructor Injection);
- Setter 注入(Setter Injection)。
屬性注入
屬性注?是使? @Autowired 實現的,例如下列代碼
// UserService
@Service
public class UserService {
public void print(){
System.out.println("hello");
}
}
// UserController
@Controller
public class UserController {
@Autowired
private UserService userService;
public void print(){
userService.print();
}
}
// Start
public class Start {
public static void main(String[] args) {
// 獲取 Spring 的上下文對象
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
UserController user = context.getBean("userController", UserController.class);
// 使用 Bean 對象
user.print();
}
}
首先可以看到 UserService 和 UserController 這兩個類都是加了類注解的,因此在程序運行后,這兩個 Bean 都是會被存放到 Spring 中。因為在 UserController 類包含了一個 UserService 對象,并且加了 @Autowired 注解,所以這個 UserService 對象就不需要 new 出來,而是會自動從 Spring 中直接獲取。這就是屬性注入
屬性注入的優點:
? 屬性注入最大的優點就是實現和使用簡單,只需要給變量上添加一個 @Autowired 注解,就可以在不 new 對象的情況下直接獲得注入的對象
屬性注入的缺點:
- 無法注入一個不可變的對象,也就是final 修飾的對象
- 只能適應于 IoC 容器
- 更容易違背單一設計原則
構造方法注入
構造方法注入是在類的構造方法中實現注入
// UserService
@Service
public class UserService {
public void print(){
System.out.println("hello");
}
}
// UserController
@Controller
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
public void print(){
userService.print();
}
}
// Start
public class Start {
public static void main(String[] args) {
// 獲取 Spring 的上下文對象
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
UserController user = context.getBean("userController", UserController.class);
// 使用 Bean 對象
user.print();
}
}
當該類中只有一個構造方法的時候,可以省略 @Autowired 注解,但是有多個構造方法時就需要在需要注入的方法上加上 @Autowired 注解
構造方法注入的優點:
- 可注入不可變對象;
- 注入對象不會被修改;(構造方法在對象創建時只會執行一次,因此它不存在注入對象被隨時(調用)修改的情況)
- 注入對象會被完全初始化;(注入的對象在使用之前會被完全初始化)
- 通用性更好。(可適用于任何環境,無論是 IoC 框架還是非 IoC 框架)
Setter 注入
Setter 注入和屬性的 Setter 方法實現類似,只不過在設置 set 方法的時候需要加上 @Autowired 注解
// UserService
@Service
public class UserService {
public void print(){
System.out.println("hello");
}
}
// UserController
@Controller
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public void print(){
userService.print();
}
}
// Start
public class Start {
public static void main(String[] args) {
// 獲取 Spring 的上下文對象
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
// 獲取 Bean 對象
UserController user = context.getBean("userController", UserController.class);
// 使用 Bean 對象
user.print();
}
}
Setter注入的優點:
- 完全符合單一職責的設計原則,一個set方法只針對一個對象
Setter注入的缺點:
- 不能注入不可變對象;(final 修飾的對象)
- 注入的對象可被修改。(因為set方法的緣故,因此對象可以被隨時隨地修改)
@Resource:另?種注入關鍵字
@Controller
public class UserController {
@Resource
private UserService userService;
public void print(){
userService.print();
}
}
@Autowired 和 @Resource 的區別:
- @Autowired 來自于 Spring,而 @Resource 來自于 JDK 的注解
- 相比于 @Autowired 來說,@Resource 支持更多的參數設置,例如 name 設置,根據名稱獲取 Bean,可以使用@Resource(name=“XXX”) 指定獲取。而 @Autowired 需要配合 @Qualifier(value = “XXX”)
- @Resource 只能用于 Setter 注入和屬性注入,不能用于構造函數注入
總結
屬性注入的寫法最簡單,所以日常項目中使用的頻率最高,但它的通用性不好;
而 Spring 官方推薦的是構造方法注入,它可以注入不可變對象,其通用性也更好。
如果是注入可變對象,那么可以考慮使用 Setter 注入
原文鏈接:https://blog.csdn.net/CHJBL/article/details/135872582
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-10-29 CSS 漸變彩色字體
- 2022-09-30 react?redux的原理以及基礎使用講解_React
- 2022-08-30 Kotlin object的用法和內存泄漏研究
- 2023-04-18 C++超詳細分析優化排序算法之堆排序_C 語言
- 2022-06-14 golang連接redis庫及基本操作示例過程_Golang
- 2022-11-08 PostgreSQL長事務與失效的索引查詢淺析介紹_PostgreSQL
- 2022-07-06 C++詳細分析講解引用的概念與使用_C 語言
- 2022-10-02 pandas數據類型之Series的具體使用_python
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支