提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- @Bean
- 一、如何使用方法注解
- 注意Bean 的命名規則,==當沒有設置 name 屬性時,那么 bean 默認的名稱就是方法名==,
- 當設置了 name 屬性之后,只能通過==重命名的name 屬性對應的值來獲取==,也就是說重命名之后,再使用方法名就獲取不到 bean 對象;
- 二、同一類型的對象注入多次的問題
- 1、精準的描述bean的名稱(將注入的名稱寫對)
- 2、使用@Resource設置name的方式來重命名注入的對象;
- 3、使用@AutoWired+@Qualifier來篩選bean對象;
- 對象注入的三種方法
- 1、屬性注入
- 2、構造方法注入
- 3、Setter方法注入
- 4. 屬性注入和構造方法注入以及 Setter 注入的區別是什么?
@Bean
一、如何使用方法注解
1、類注解是寫到類上面的,那么方法注解是寫到對應的方法上的;
@Bean(name = "user1") public User getUser1() {User user = new User();user.setId(1);user.setName("張三");return user;}
2、方法注解的話是不能夠單獨使用的,如果我們只給一個方法注解@Bean的話,看是否能運行;
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");User user = context.getBean(User.class);//只使用類屬性System.out.println(user);
運行結果:
如何解決?我們只需要在方法注解的類中添加一個類注解即可;
再次運行:
注意Bean 的命名規則,當沒有設置 name 屬性時,那么 bean 默認的名稱就是方法名,
當設置了 name 屬性之后,只能通過重命名的name 屬性對應的值來獲取,也就是說重命名之后,再使用方法名就獲取不到 bean 對象;
比如已經給bean重命名了,我們在啟動類App中通過方法名來獲取Bean對象;
看運行結果:
二、同一類型的對象注入多次的問題
1、在UserBeans類中寫兩個對象注解;
@Component
public class UserBeans {@Bean(name = "user1") // 【注意事項:只使用一個 @Bean 是無法將對象存儲到容器中的】public User getUser1() {User user = new User();user.setId(1);user.setName("張三");return user;}@Bean(name = "user2") // 【注意事項:只使用一個 @Bean 是無法將對象存儲到容器中的】public User getUser2() {User user = new User();user.setId(2);user.setName("李四");return user;}
2、通過啟動類來獲取對象;
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
User user = context.getBean(User.class);//只使用類屬性
System.out.println(user);
翻譯過來的意思就是:沒有可用的“com.User”類型的合格bean:應為單個匹配bean,但找到2:user1,user2;
那么,如何解決呢?這里我們提供了三種解決方案;
1、精準的描述bean的名稱(將注入的名稱寫對)
比如我們在啟動類中使用id+class的形式來取對象;
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
User user = context.getBean("user1",User.class);//只使用類屬性
System.out.println(user);
2、使用@Resource設置name的方式來重命名注入的對象;
1、這里我們通過UserController類來進行演示;注意我們添加的注解@Resource,下面新寫了一個對象user1;
package com;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller
public class UserController {@Resourceprivate User user1;public void sayHi(){System.out.println("User"+user1);}
}
啟動類App中代碼:
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
UserController userController = context.getBean(UserController.class);
userController.sayHi();
3、使用@AutoWired+@Qualifier來篩選bean對象;
UserController代碼:
package com;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller
public class UserController {@Autowired@Qualifier(value = "user2")private User user2;public void sayHi(){System.out.println("User"+user2);}
}
對象注入的三種方法
1、屬性注入
屬性注?是使? @Autowired 實現的,將 Service 類注?到 Controller 類中。
package com;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
/*** 根據屬性實現 bean 對象的注入*/
@Controller
public class UserController2 {// 對象注入方式1:屬性注入@Autowiredprivate UserService userService;public void sayHi() {userService.sayHi();}}
啟動類App:
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
UserController2 userController2 = context.getBean(UserController2.class);
userController2.sayHi();
2、構造方法注入
package com;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;/*** 使用構造方法實現 bean 注入*/
@Controller
public class UserController3 {private UserService userService;// 構造方法注入(官廣推薦寫法)@Autowiredpublic UserController3(UserService userService) {
// userService = new UserService(); // 傳統的寫法this.userService = userService;}public void sayHi() {userService.sayHi();}}
注:如果當前類只存在一個構造方法,那么@Autowired注解可以省略;
啟動類App:
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
UserController3 userController3 = context.getBean(UserController3.class);
userController3.sayHi();
3、Setter方法注入
package com;import org.springframework.stereotype.Controller;import javax.annotation.Resource;/*** 使用 Setter 實現 bean 注入*/
@Controller
public class UserController4 {private UserService userService;@Resourcepublic void setUserService(UserService userService) {this.userService = userService;}public void sayHi() {userService.sayHi();}}
啟動類App:
ApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
UserController4 userController4 = context.getBean(UserController4.class);
userController4.sayHi();
4. 屬性注入和構造方法注入以及 Setter 注入的區別是什么?
- 屬性注入:特點寫法簡單。但是通用性不好,它只能運行在 IoC 容器下,如果是非 IOC 容器就會出現問題。
- Setter 注入:早期 Spring 版本推薦的寫法,Setter 注入通用性沒有構造方法注入通用。
- 構造方法注入: 通用性更好、它能確保在使用注入對象之前,此注入對象一定初始化過了。當構造方法注入參數過多時,此時開發者就要檢查自己所寫的代碼是否符合單一設計原則的規范了,此注入方式也是 spring后期版本中推薦的注入方式。