1. 存儲bean對象
存儲 Bean 分為以下 2 步:
- 存儲 Bean 之前,先得有 Bean 才?,因此先要創(chuàng)建?個 Bean, 說白了也就是寫一個類。
- 告訴spring,把這個類的對象存起來。
1.1 使用配置文件存儲bean對象
- 編寫
User
類, 有sayHi
方法。
public class User {
public void sayHi() {
System.out.println("你好");
}
}
- 告訴
spring
,把這個類的對象存起來。
在配置文件中可以通過<bean>
標簽來告訴spring
把對象存起來。
<bean id="user1" class="demo.User"></bean>
-
id
: 是用來標識一個對象的,就像我們的身份證一樣。
也稱為bean對象的name(名字)
, 后面通過這個名字就能找到這個對象。 -
class
:是帶包的類名, 讓spring
知道我們要存的是哪一個類的對象。
完整的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:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="user1" class="demo.User"></bean>
</beans>
注意:配置文件其他的標簽不用管,直接復制粘貼,需要關(guān)注的是<bean>
標簽。
怎么知道Spring
把對象存起來了呢?我們查找一下這個bean
對象的name
(名字) 就行了。
使用BeanFactory
或者ClassPathXmlApplicationContext
就能查找bean
對象了。
用BeanFactory
的代碼如下:
public class Test {
public static void main(String[] args) {
//創(chuàng)建BeanFactory的實現(xiàn)類的對象
BeanFactory beanFactory =
new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
//根據(jù)名字查找bean對象
User user1 = (User)beanFactory.getBean("user1");
//調(diào)用sayHi()方法
user1.sayHi();
}
}
結(jié)果:
如何創(chuàng)建BeanFactory
對象:
-
BeanFactory
是一個接口,XmlBeanFactory
是其中的一個實現(xiàn)類,因為我們用xml
文件來告訴spring
存儲bean
對象,所以用XmlBeanFactory
這個類。 -
XmlBeanFactory
其中的一個構(gòu)造器的參數(shù)類型是:Resource
。Resource
也是一個接口, 所以還需要創(chuàng)建Resource
接口的實現(xiàn)類。
使用ClassPathXmlApplicationContext
上下文對象,查找bean
對象。
public class Test {
public static void main(String[] args) {
test2();
}
public static void test2() {
//創(chuàng)建上下文對象
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//查找bean對象,第二個參數(shù)傳了User的類型,得到bean對象后就無需轉(zhuǎn)型了
User user1 = context.getBean("user1", User.class);
user1.sayHi();
}
}
結(jié)果:
1.2 使用五大類注解存儲bean對象
用xml
的形式來存儲對象會比較麻煩,如果需要存很多個對象,就需要在xml
配置文件中寫多個<bean>
標簽。
這樣子會很麻煩。所以spring
提供了更加簡便的方式來存儲bean
對象, 那就是使用注解。
下面介紹使用注解存儲bean
對象。
使用注解的方式,也要配置xml
文件,不過只需要配置一個標簽:<content:component-scan>
配置文件如下:
<?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:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="demo"></content:component-scan>
</beans>
說明:<content:component-scan>
這個標簽用來配置包掃描路徑, base-package="demo"
配置的就是具體的包。
作用就是告訴spring
在哪個包下掃描帶有注解的類。spring
掃描到帶有注解的類就會為這個類創(chuàng)建對象。
<content:component-scan base-package="demo"></content:component-scan>
想要將對象存儲在 Spring 中,有兩種注解類型可以實現(xiàn):
- 類注解:
@Controller
(控制器)、@Service
(服務)、@Repository
(倉庫)、@Component
(組件)、@Configuration
(配置)。 - ?法注解:
@Bean
1.2.1 類注解
- 使用
@Controller
類注解
在下面的代碼中創(chuàng)建了ControllerTest
類,有sayHello
方法,類的上面有@Controller
注解
有了這個@Controller
注解,spring
就能掃描到這個類,然后spring
就會創(chuàng)建對象了。
@Controller
public class ControllerTest {
public void sayHello() {
System.out.println("hello, 正在測試@Controller注解");
}
}
測試類:
public class Test {
public static void main(String[] args) {
test3();
}
public static void test3() {
//創(chuàng)建上下文對象
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//獲取bean對象, 如果沒有在注解上加參數(shù),默認用類名的首字母小寫獲取bean對象
ControllerTest controllerTest = context.getBean("controllerTest", ControllerTest.class);
controllerTest.sayHello();
}
結(jié)果:
注意:
如果在注解上沒有指定bean
對象的名字,將類名的首字母小寫后作為bean
對象的名字獲取bean
對象。ControllerTest
類名小寫后是controllerTest
,所以用controllerTest
可以獲取到bean
對象。
也可以在注解上傳參,指定bean
對象的名字。
根據(jù)名字獲取bean
對象
- 使用
@Service
注解@Service
注解跟@Controller
的用法幾乎一模一樣。
@Service
public class ServiceTest {
public void sayHello() {
System.out.println("hello, 正在測試@Service注解");
}
}
public class Test {
public static void main(String[] args) {
test4();
}
public static void test4() {
//創(chuàng)建上下文對象
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//獲取bean對象, 如果沒有在注解上加參數(shù),默認用類名的首字母小寫獲取bean對象
ServiceTest serviceTest = context.getBean("serviceTest", ServiceTest.class);
serviceTest.sayHello();
}
}
@Repository
, @Component
, @Configuarion
注解用法跟上面的代碼差不多,就不再演示了。
1.2.2 五大類注解的作用
因為后端程序是分層的,這五個類注解,分別就代表不同的層。@Controller
代表了業(yè)務邏輯層。@Service
代表了服務層。@Repository
代表了數(shù)據(jù)層。@Configuration
是配置層。
這些類注解功能是一樣的,都是告訴spring
存儲bean
對象。
但是當我們看到一個類上帶了@Controller
注解的時候,我們就清楚了,這個類處于 哪一層的,是干什么的。
這樣做這樣可以大大提高程序的可閱讀性。
1.2.3 方法注解
@Bean
方法注解用來將方法返回的對象存到spring
中。
在ControllerTest
類中,寫一個getObj
方法,這個方法返回的ArrayList
對象會存到spring
中
@Controller("con")
public class ControllerTest {
public void sayHello() {
System.out.println("hello, 正在測試@Controller注解");
}
@Bean(name = "list")
public ArrayList<Integer> getObj() {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
return list;
}
}
測試列:
public class Test {
public static void main(String[] args) {
test5();
}
public static void test5() {
//創(chuàng)建上下文對象
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//根據(jù)name獲取bean對象
ArrayList<Integer> list = context.getBean("list", ArrayList.class);
System.out.println(list.get(0));
}
}
輸出:
2.獲取bean對象
獲取 bean 對象也叫做對象裝配,是把對象取出來放到某個類中,也可以叫對象注?。
對象注?的實現(xiàn)?法以下 3 種:
- 屬性注?
- 構(gòu)造?法注?
- Setter 注?
使用@Autowired
或者@Resource
注解實現(xiàn)spring中的bean對象注入。
這里用@Autowired
注解進行演示。
2.1 屬性注入
UserService
類
@Service
public class UserService {
public void sayHi() {
System.out.println("Hi");
}
}
UserController
類
獲取spring
中的對象使用@Autowired
注解,將UserService
類的bean
對象注入進來
@Controller
public class UserController {
@Autowired
private UserService userService;
public void sayHi() {
userService.sayHi();
}
}
測試類:
public class Test {
public static void main(String[] args) {
test6();
}
public static void test6() {
//創(chuàng)建上下文對象
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//獲取bean對象
UserController userController = context.getBean("userController", UserController.class);
userController.sayHi();
}
}
輸出了Hi
,UserSevice
類的bean
對象成功被注入了。
2.2 構(gòu)造器注入
將@Autowired
注解放在構(gòu)造器的上面,加一個形參,就可以實現(xiàn)構(gòu)造器注入了。
@Controller
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
public void sayHi() {
userService.sayHi();
}
}
2.3 getter注入
getter
注入也一樣,將@Autowired
注解放在getter
方法上即可。
@Controller
public class UserController {
private UserService userService;
public void sayHi() {
userService.sayHi();
}
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
2.4 注入對象的時候有spring中有多個bean對象怎么辦
當注入對象的時候,spring
中有多個對象的時候,就要告訴spring
獲取的是哪個bean
對象。
但是@Autowired
注解不能傳入bean
對象的名字,所以要用其他的方式來解決這個問題。
這時候有三種做法:
- 將類中屬性的名字,改成和要注入的
bean
對象的名字一樣 - 在
@Autowired
注解下面加@Qualifier
注解 - 拋棄
@Autowired
注解, 使用@Resource
注解
下面演示這三種不同處理方法:
2.4.1 將類中屬性的名字,改成和要注入的bean
對象的名字一樣
Student
類, 有id
、name
、age
屬性, set
方法和toString
方法。
public class Student {
private int id;
private String name;
private int age;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
StudentService
類, 使用了方法注解@Bean
將兩個Student類
的對象存到spring
中。
@Service
public class StudentService {
@Bean("stu1")
public Student getStu1() {
Student student = new Student();
student.setId(1);
student.setName("張三");
student.setAge(22);
return student;
}
@Bean("stu2")
public Student getStu2() {
Student student = new Student();
student.setId(2);
student.setName("李四");
student.setAge(23);
return student;
}
}
StudentController
類中,有屬性stu1
和showStuInfo
方法, 使用@Autowired
將對象注入到屬性上。
@Controller("stucon")
public class StudentController {
@Autowired
private Student stu1;
public void showStuInfo() {
System.out.println(stu1.toString());
}
}
stu1屬性名和bean對象的名字一樣。
測試類:
public class Test {
public static void main(String[] args) {
test7();
}
public static void test7() {
//創(chuàng)建上下文對象
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
StudentController studentController = context.getBean("stucon", StudentController.class);
studentController.showStuInfo();
}
}
輸入出:
2.4.2 在 @Autowired
注解下面加@Qualifier
注解
@Qualifier
注解的源碼,使用注解的時候,可以傳遞value
的值
在@Qualifier
注解的中加上bean
對象的名字,spring
就知道要注入哪一個bean
對象了。
StudentController
類如下。
@Controller("stucon")
public class StudentController {
@Autowired
@Qualifier("stu1")
private Student stu;
public void showStuInfo() {
System.out.println(stu.toString());
}
}
2.4.3 拋棄@Autowired
注解, 使用@Resource
注解
@Resource
注解的部分源碼。
在注解上傳遞一個參數(shù)即可,name = "stu1"
就表示要注入名為stu1
的bean
對象
@Controller("stucon")
public class StudentController {
@Resource(name = "stu1")
private Student stu;
public void showStuInfo() {
System.out.println(stu.toString());
}
}
2. 5 @Autowired和@Resource注解的區(qū)別
- 出身不同。
@Autowired
來自于spring
,而@Resource
是JDK
自帶的。 - 傳參不同。
@Resource
相比@Autowired
,可以傳遞的參數(shù)更多。 -
@Autowired
注解可以用于屬性注入,構(gòu)造方法注入,setter注入。
而@Resource
注解只能用于屬性注入和setter注入, 不同用于構(gòu)造方法注入。
因為@Autowried
注解可以修飾屬性,構(gòu)造器,和方法,@Resource
不能修飾構(gòu)造器,但可以修飾屬性和方法。
@Autowried
注解部分源碼
@Resource
注解部分源碼文章來源:http://www.zghlxwxcb.cn/news/detail-612659.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-612659.html
到了這里,關(guān)于spring中存儲和獲取bean對象的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!