??前言??
在上一篇文章【Spring的創(chuàng)建與使用】中,我們已經(jīng)了解了Spring中bean對象的基本的創(chuàng)建和使用方法,這篇文章通過注解的方法,使得存儲和讀取對象更加簡單。
🍉博客主頁: 🍁【如風暖陽】🍁
🍉精品Java專欄【JavaSE】、【備戰(zhàn)藍橋】、【JavaEE初階】、【MySQL】、【數(shù)據(jù)結構】
🍉歡迎點贊 👍 收藏 ?留言評論 📝私信必回喲😁🍉本文由 【如風暖陽】 原創(chuàng),首發(fā)于 🙉
🍉博主將持續(xù)更新學習記錄收獲,友友們有任何問題可以在評論區(qū)留言
🍉博客中涉及源碼及博主日常練習代碼均已上傳碼云(gitee)、GitHub
簡單的將Bean存儲到容器,有以下幾種方法:
a)使用5大類注解實現(xiàn)
b)通過@Bean方法注解
下標我們一起來看具體的實現(xiàn)方式。
1.1 前置工作在使用更簡單的方法存儲和讀取bean對象之前,先完成前置工作——在Spring配置文件中設置bean的掃描根路徑:
1.2 使用5大類注解實現(xiàn)存儲
1.2.1 @Controller(控制器存儲)使? @Controller 存儲 bean 的代碼如下所示:
@Controller
public class UserController {public void sayHi() {System.out.println("你好,Contorller");
}
}
我們先使?之前讀取對象的?式來讀取上?的 UserController 對象,如下代碼所示:
public class App {public static void main(String[] args) {//1.得到Spring上下文
ApplicationContext context=
new ClassPathXmlApplicationContext("spring-config.xml");
//2.得到bean
UserController userController=context.getBean("userController",UserController.class);
//3.使用bean
userController.sayHi();
}
}
此處我們的beanName依舊是類名的小駝峰命名法,在后邊我們會具體講述Spring使用五大類注解生成beanName的問題。
1.2.2 @Service(服務存儲)使? @Service 存儲 bean 的代碼如下所示:
@Service
public class UserService {public void sayHi() {System.out.println("你好,Service");
}
}
讀取bean的代碼:
public class App {public static void main(String[] args) {//1.得到Spring上下文
ApplicationContext context=
new ClassPathXmlApplicationContext("spring-config.xml");
//2.得到bean
UserService userService=context.getBean("userService",UserService.class);
//3.使用bean
userService.sayHi();
}
}
1.2.3 @Repository(倉庫存儲)使? @Repository 存儲 bean 的代碼如下所示:
@Repository
public class UserRepository {public void sayHi() {System.out.println("你好,Repository");
}
}
讀取 bean 的代碼:
public class App {public static void main(String[] args) {//1.得到Spring上下文
ApplicationContext context=
new ClassPathXmlApplicationContext("spring-config.xml");
//2.得到bean
UserRepository userRepository=context.getBean("userRepository",UserRepository.class);
//3.使用bean
userRepository.sayHi();
}
}
1.2.4 @Component(組件存儲)使? @Component 存儲 bean 的代碼如下所示:
@Component
public class UserComponent {public void sayHi() {System.out.println("你好,Component");
}
}
讀取 bean 的代碼:
public class App {public static void main(String[] args) {//1.得到Spring上下文
ApplicationContext context=
new ClassPathXmlApplicationContext("spring-config.xml");
//2.得到bean
UserComponent userComponent=context.getBean("userComponent",UserComponent.class);
//3.使用bean
userComponent.sayHi();
}
}
1.2.5 @Configuration(配置存儲)使? @Configuration 存儲 bean 的代碼如下所示:
@Configuration
public class UserConfiguration {public void sayHi() {System.out.println("你好,Configuration");
}
}
讀取 bean 的代碼:
public class App {public static void main(String[] args) {//1.得到Spring上下文
ApplicationContext context=
new ClassPathXmlApplicationContext("spring-config.xml");
//2.得到bean
UserConfiguration userConfiguration=context.getBean("userConfiguration",UserConfiguration.class);
//3.使用bean
userConfiguration.sayHi();
}
}
1.3 為什么需要這么多的注解?既然上述的五大類注解都能夠完成將Bean對象存儲到Spring中的功能,那為什么需要這么多的注解呢?
這是因為不同的注解有不同的用途,在程序猿看到類注解后,就能直接了解當前類的用途,增加了代碼的可讀性。
程序的工程分層,調(diào)用流程如下:
查看 @Controller / @Service / @Repository / @Configuration 等注解的源碼發(fā)現(xiàn):
這些注解里都有一個注解@Component,說明它們本身就是屬于@Component的“子類”。
在1.2所有的獲取bean對象的方法中,使用到的beanName都是小駝峰命名,但如果出現(xiàn)以下bean,還能通過小駝峰獲取到嗎?
@Controller
public class APIController {public void sayHi() {System.out.println("你好,APIController");
}
}
在我們?nèi)ミ€以小駝峰命名法去獲取bean對象時,發(fā)現(xiàn)報錯,說明并不是所有的beanName都是以小駝峰命名法來命名的。
我們來查看beanName的命名規(guī)則源碼:
(關于注解beanName的生成器)
我們來看bean對象的命名規(guī)則的方法:
它使?的是 JDK Introspector 中的 decapitalize ?法,源碼如下:
public static String decapitalize(String name) { if (name == null || name.length() == 0) { return name;
}
// 如果第?個字?和第?個字?都為?寫的情況,是把 bean 的?字?也?寫存儲了
if (name.length() >1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){ return name;
}
// 否則就將?字??寫
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
如果第?個字母和第?個字母都為?寫的情況,是把 bean 的?字母也?寫存儲了,否則就將?字母?寫
所以對于上?報錯的代碼,我們只要改為以下代碼就可以正常運?了:
類注解是添加到某個類上的,而方法注解是放到某個方法上的,但僅依靠方法注解是仍然獲取不到bean的,還需要搭配類注解:
1.6.1 方法注解要搭配類注解使用先完成類代碼:
public class User {private int id;
private String name;
@Override
public String toString() {return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public int getId() {return id;
}
public void setId(int id) {this.id = id;
}
public String getName() {return name;
}
public void setName(String name) {this.name = name;
}
}
@Component
public class UserBeans {@Bean
public User getUser() {User user=new User();
user.setId(1);
user.setName("張三");
return user;
}
}
使用User類:
我們發(fā)現(xiàn)這樣也可以獲得User
對象,但是beanName
很別扭(也可以只通過bean type
來獲取該類,但如果出現(xiàn)多次存儲的情況就會報錯),因為是方法名,而不是類名的小駝峰,所以我們可以通過設置name
屬性給Bean
對象,進行重命名操作,下邊看具體演示:
可以通過設置name屬性給Bean對象進行重命名操作,如下代碼所示:
@Component
public class UserBeans {@Bean(name="u1")
public User getUser() {User user=new User();
user.setId(1);
user.setName("張三");
return user;
}
}
此時我們使用u1就可以獲取到User對象了,如下代碼所示:
獲取bean對象也叫做對象裝配,是把對象取出來放到某個類中,有時候也叫對象注入。
對象裝配(對象注入)的實現(xiàn)方法有以下三種:
下邊我們按照實際開發(fā)中的模式,將Service類注入到Controller類中。
2.1 屬性注入屬性注入是使用@Autowired
實現(xiàn)的,將Service
類注入到Controller
類中。
Service
類的實現(xiàn)代碼如下:
@Service
public class UserService {public void sayHi() {System.out.println("你好,Service");
}
}
Controller
類的實現(xiàn)代碼如下:
@Controller
public class UserController2 {//屬性注入
@Autowired
private UserService userService;
public void sayHi() {userService.sayHi();
}
}
獲取Controller
中的sayHi
?法:
構造方法注入是在類的構造方法上,使用@Autowired
實現(xiàn)注入,如下代碼所示:
@Controller
public class UserController3 {private UserService userService;
//構造方法注入
@Autowired
public UserController3(UserService userService) {this.userService = userService;
}
public void sayHi() {userService.sayHi();
}
}
注意:
如果只有一個構造方法,那么@Autowired
注釋可以省略,但如果類中有多個構造方法,就必須加上注解來明確指定到底使用哪個構造方法,否則會報錯。
Setter
注入和屬性的Setter方法實現(xiàn)類似,只不過在設置set
方法的時候需要加上@Autowired
注解,如下代碼所示:
@Controller
public class UserController4 {private UserService userService;
//Setter注入
@Autowired
public void setUserService(UserService userService) {this.userService=userService;
}
public void sayHi() {userService.sayHi();
}
}
2.4 三種注入方式的區(qū)別@Resourse
該注入注解與@Autowired
功能幾乎相同,但也有差別,下邊看兩者的具體差別:
1、出身不同:@Resourse
來自于JDK,而@Autowired
是Spring框架提供的。
2、用法不同:@Autowired
支持屬性注入、構造方法注入和Setter注入,而@Resourse
比前者少一個,它不支持構造方法注入。
3、支持的參數(shù)不同:@Resourse
支持更多的參數(shù)設置,比如name
、type
設置,而@Autowired
只支持required
參數(shù)設置。
當出現(xiàn)以下多個Bean,返回同一對象類型時程序會報錯,如下代碼所示:
@Component
public class UserBeans {@Bean(name="u1")
public User getUser1() {User user=new User();
user.setId(1);
user.setName("張三");
return user;
}
@Bean(name="u2")
public User getUser2() {User user=new User();
user.setId(2);
user.setName("李四");
return user;
}
}
在另一個類中獲取User對象,如下代碼所示:
@Controller
public class UserController {@Resource
private User user;
public void sayHi() {System.out.println("user->"+user);
}
}
運行結果如下:
報錯的原因是非唯一的Bean對象。
同一個類型多個Bean的報錯處理有以下三種方式:
1、精確地描述bean
的名稱(將注入的名稱寫對)
2、使用@Resourse
設置name的方式來重命名注入對象
3、使用@Autowired
+@Qualifier
來篩選bean對象
1、將對象存儲到Spring
中:
@Controller
、@Service
、@Repository
、@Configuration
、@Component
【了解它們之間的關系與區(qū)別】@Bean
【注意搭配類注解一起使用】2、Bean的命名規(guī)則:
首字母和第二個字母都是大寫,那么直接使用原Bean名來獲取Bean,否則就讓首字母小寫(小駝峰)來獲取Bean。
3、從Spring中獲取對象:
4、注入的關鍵字:
@Autowired
@Resourse
5、@Autowired
和@Resourse
的區(qū)別:
@Resourse
不支持構造方法注入@Resourse
支持更多的參數(shù)6、解決同一類型多個Bean
的報錯:
@Resourse(name="")
@Autowired @Qulifier("value =")
??最后的話??
總結不易,希望uu們不要吝嗇你們的👍喲(^U^)ノ~YO??!如有問題,歡迎評論區(qū)批評指正😁
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧