Spring?Bean注冊與注入實(shí)現(xiàn)方法詳解
上接【Spring】spring核心思想——IOC和DI
上篇文章結(jié)尾簡單介紹了一下使用 XML 注冊 Bean,這篇文章接著介紹一下 XML 注冊 Bean 和使用注解注冊、注入 Bean
1. 邏輯上的 Bean 注冊

2. XML 注冊 Bean 到自建的庫中
上篇文章介紹了使用 XML 三種注冊的三種方式 (直接注入、構(gòu)造方法注入、set 方法注入),在這里繼續(xù)介紹一下使用工廠方法 和 實(shí)例化工廠注冊 Bean
2.1 工廠方法
工廠方法分為靜態(tài)工廠方法和實(shí)例工廠方法
使用工廠方法注冊就是調(diào)用靜態(tài)工廠方法注冊 Bean
實(shí)例化工廠注冊就是調(diào)用實(shí)例工廠方法注冊 Bean
2.2 使用工廠方法和實(shí)例化工廠注冊 Bean
首先還是使用 XML 自建庫,在 Main 方法中對庫進(jìn)行操作(這里對庫的操作主要是打印 Bean)
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
public static void main(String[] args) {
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("spring-config.xml");
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
Object bean = context.getBean(name);
String canonicalName = bean.getClass().getCanonicalName();
System.out.println(name + " " + canonicalName);
}
int count = context.getBeanDefinitionCount();
System.out.println("一共有 " + count + "個(gè)");
}
}<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 通過工廠注冊,bean 的實(shí)例化由工廠方法完成-->
<bean id="工廠注冊" class="com.hsq.ioc3.SomeClass" factory-method="createPerson"/>
<!-- 通過已經(jīng)注冊的 bean 的實(shí)例方法注冊,bean 的實(shí)例化由我們自己完成-->
<bean id="工具bean" class="com.hsq.ioc3.SomeClass"/>
<bean id="通過實(shí)例化工廠注冊" factory-bean="工具bean" factory-method="instantCreatePerson"/>
</beans>public class SomeClass {
// 靜態(tài)方法(可以直接通過類名調(diào)用)
// 作用:返回一個(gè)對象
// 這類方法被稱為工廠方法
public static Person createPerson() {
System.out.println("createPerson 被調(diào)用");
return new Person();
}
public Person instantCreatePerson() {
System.out.println("instantCreatePerson 被調(diào)用");
return new Person();
}
}public class Person {
public Person() {
System.out.println("Person 被調(diào)用");
}
}
通過打印可以清楚的看到兩種方法都成功注冊 Person 對象

3. XML 配合注解進(jìn)行 Bean 注冊
自建 XML 庫中的配置文件有所改變
用到的注解 @Component,此注解后邊會(huì)講到
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 掃描這個(gè)包下的所有類,如果沒在這個(gè)包下,即使加了注解接不會(huì)被注入-->
<context:component-scan base-package="com.hsq.ioc3"/>
</beans>
import org.springframework.stereotype.Component;
@Component
public class World {
public World() {
System.out.println("World 被調(diào)用");
}
}通過打印可以清楚看到,World 對象被成功注冊

4. 使用注解注冊 Bean
使用注解注冊簡而言之就是使用某個(gè)注解修飾類或方法,對其進(jìn)行注冊
使用注解注冊 Bean 是注冊進(jìn) Spring 提供的庫,就不需要自建庫了
4.1 注解方式注冊的必要條件
- 要被注解修飾類
- 被注冊的 Bean 要在 XXXApplication 所在包下,否則注冊不會(huì)成功
4.2 用到的注解
這幾個(gè)注解在 IOC 場景下,沒有區(qū)別,都是將類注冊進(jìn) Spring 庫,但在其他場景一般這樣用
@Component:沒有特殊作用時(shí),都可以用
@Controller:SpringMVC中把此注解特殊化了,要求控制器類必須用此注解修飾
@Service:修飾中間數(shù)據(jù)整合的類
@Repository:修飾數(shù)據(jù)獲取類
@Configuration:修飾配置類
4.3 @Component注解注入
import org.springframework.stereotype.Component;
@Component
public class World {
public World() {
System.out.println("World() 被調(diào)用");
}
}@SpringBootApplication
public class IocAApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(IocAApplication.class, args);
String[] names = context.getBeanDefinitionNames();
System.out.println("bean 陳列如下:");
for (String name : names) {
Object bean = context.getBean(name);
String canonicalName = bean.getClass().getCanonicalName();
System.out.println(name + " " + canonicalName);
}
int count = context.getBeanDefinitionCount();
System.out.println("一共 " + count + "個(gè)");
}
}通過打印清楚看到,對象被注冊

4.4 使用 @Bean 注解注冊
使用 @Bean 修飾方法,@Configuration 修飾類
此方法注冊就相當(dāng)于 XML 中的工廠方法注冊
@Configuration
public class AppConfig {
// <bean id="hsq" factory-bean="appConfig" factory-method="hsq" />
// 以工廠方法注冊
@Bean
public String hsq() {
return "hsq";
}
@Bean // 這里的 World 由 Spring 注入
// 因?yàn)?createHello 被 Spring 調(diào)用
public Hello createHello(@Autowired World world) {
System.out.println("createHello(), world = " + world);
return new Hello(world);
}
}
5. 通過注解注入 Bean
需要用到 World 類時(shí)
- 先讓 Hello 類被注冊到 Spring 容器,并且實(shí)例化過程交給 Spring。———— @Component 修飾 Hello 類
- 要求 World 類被注冊到 Spring 中(類注冊或者方法注冊都可以)
- 使用構(gòu)造方法、set 方法、屬性直接注入三種方法注入bean——使用 @Autowired 修飾
import org.springframework.stereotype.Component;
@Component
public class World {
public World() {
System.out.println("World() 被調(diào)用");
}
}構(gòu)造方法注入
@Component
public class Hello {
@Autowired // 這個(gè)注解其實(shí)可以不寫,但是建議寫上,主要是讓看代碼的人知道我們的 World 對象是被注入的
// 如果有多個(gè)構(gòu)造方法,告訴 Spring,實(shí)例化對象是,應(yīng)該調(diào)用哪個(gè)
public Hello(World world) {
System.out.println("Hello(), world = " + world);
}
}set 方法注入
@Component
public class Hello2 {
@Autowired // 這里的此注解必須寫上
public void setWorld(World world) {
System.out.println("setWorld(), World = " + world);
}
}
屬性直接注入
@Component
public class Hello3 {
@Autowired
public World world; // world 屬性的值會(huì)被 Spring 容器對象注入
public void printWorld() {
System.out.println("printWorld(), world = " + this.world);
}
}
6. 注入時(shí)的一個(gè)坑點(diǎn)
當(dāng)使用以下方法注入時(shí),會(huì)注入進(jìn) NULL 值,而非對象,原因已在下面代碼的注釋中寫出
// 發(fā)生在 set 注入 / 屬性直接注入上
@Component
public class 注入時(shí)的一個(gè)坑點(diǎn) {
@Autowired
public World world;
public 注入時(shí)的一個(gè)坑點(diǎn)() {
// 構(gòu)造方法先執(zhí)行,然后再進(jìn)行注入(屬性注入 / set 注入)
// 所以,構(gòu)造方法執(zhí)行的時(shí)候,注入還沒有發(fā)生,所以還是 null
// 所以一般建議使用構(gòu)造方法注入
System.out.println("注入時(shí)的一個(gè)坑點(diǎn)(), world = " + this.world);
}
}7. 獲取 庫中的對象
ConfigurableApplicationContext context = SpringApplication.run(IocAApplication.class, args);
Object world1 = context.getBean("world"); // 根據(jù) id 獲取 bean
World world2 = context.getBean(World.class); // 根據(jù)類型獲取 bean
World world = context.getBean("world", World.class); // 根據(jù) id + 類型獲取 bean到此這篇關(guān)于Spring Bean注冊與注入實(shí)現(xiàn)方法詳解的文章就介紹到這了,更多相關(guān)Spring Bean注冊與注入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
redis實(shí)現(xiàn)分布式鎖實(shí)例詳解
這篇文章主要為大家詳細(xì)介紹了redis實(shí)現(xiàn)分布式鎖實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03
Java 執(zhí)行CMD命令或執(zhí)行BAT批處理方式
這篇文章主要介紹了Java 執(zhí)行CMD命令或執(zhí)行BAT批處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08

