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

2. XML 注冊 Bean 到自建的庫中
上篇文章介紹了使用 XML 三種注冊的三種方式 (直接注入、構(gòu)造方法注入、set 方法注入),在這里繼續(xù)介紹一下使用工廠方法 和 實例化工廠注冊 Bean
2.1 工廠方法
工廠方法分為靜態(tài)工廠方法和實例工廠方法
使用工廠方法注冊就是調(diào)用靜態(tài)工廠方法注冊 Bean
實例化工廠注冊就是調(diào)用實例工廠方法注冊 Bean
2.2 使用工廠方法和實例化工廠注冊 Bean
首先還是使用 XML 自建庫,在 Main 方法中對庫進行操作(這里對庫的操作主要是打印 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 + "個");
}
}<?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 的實例化由工廠方法完成-->
<bean id="工廠注冊" class="com.hsq.ioc3.SomeClass" factory-method="createPerson"/>
<!-- 通過已經(jīng)注冊的 bean 的實例方法注冊,bean 的實例化由我們自己完成-->
<bean id="工具bean" class="com.hsq.ioc3.SomeClass"/>
<bean id="通過實例化工廠注冊" factory-bean="工具bean" factory-method="instantCreatePerson"/>
</beans>public class SomeClass {
// 靜態(tài)方法(可以直接通過類名調(diào)用)
// 作用:返回一個對象
// 這類方法被稱為工廠方法
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 配合注解進行 Bean 注冊
自建 XML 庫中的配置文件有所改變
用到的注解 @Component,此注解后邊會講到
<?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">
<!-- 掃描這個包下的所有類,如果沒在這個包下,即使加了注解接不會被注入-->
<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
使用注解注冊簡而言之就是使用某個注解修飾類或方法,對其進行注冊
使用注解注冊 Bean 是注冊進 Spring 提供的庫,就不需要自建庫了
4.1 注解方式注冊的必要條件
- 要被注解修飾類
- 被注冊的 Bean 要在 XXXApplication 所在包下,否則注冊不會成功
4.2 用到的注解
這幾個注解在 IOC 場景下,沒有區(qū)別,都是將類注冊進 Spring 庫,但在其他場景一般這樣用
@Component:沒有特殊作用時,都可以用
@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 + "個");
}
}通過打印清楚看到,對象被注冊

4.4 使用 @Bean 注解注冊
使用 @Bean 修飾方法,@Configuration 修飾類
此方法注冊就相當于 XML 中的工廠方法注冊
@Configuration
public class AppConfig {
// <bean id="hsq" factory-bean="appConfig" factory-method="hsq" />
// 以工廠方法注冊
@Bean
public String hsq() {
return "hsq";
}
@Bean // 這里的 World 由 Spring 注入
// 因為 createHello 被 Spring 調(diào)用
public Hello createHello(@Autowired World world) {
System.out.println("createHello(), world = " + world);
return new Hello(world);
}
}
5. 通過注解注入 Bean
需要用到 World 類時
- 先讓 Hello 類被注冊到 Spring 容器,并且實例化過程交給 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 // 這個注解其實可以不寫,但是建議寫上,主要是讓看代碼的人知道我們的 World 對象是被注入的
// 如果有多個構(gòu)造方法,告訴 Spring,實例化對象是,應(yīng)該調(diào)用哪個
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 屬性的值會被 Spring 容器對象注入
public void printWorld() {
System.out.println("printWorld(), world = " + this.world);
}
}
6. 注入時的一個坑點
當使用以下方法注入時,會注入進 NULL 值,而非對象,原因已在下面代碼的注釋中寫出
// 發(fā)生在 set 注入 / 屬性直接注入上
@Component
public class 注入時的一個坑點 {
@Autowired
public World world;
public 注入時的一個坑點() {
// 構(gòu)造方法先執(zhí)行,然后再進行注入(屬性注入 / set 注入)
// 所以,構(gòu)造方法執(zhí)行的時候,注入還沒有發(fā)生,所以還是 null
// 所以一般建議使用構(gòu)造方法注入
System.out.println("注入時的一個坑點(), 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注冊與注入實現(xiàn)方法詳解的文章就介紹到這了,更多相關(guān)Spring Bean注冊與注入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java動態(tài)代理實現(xiàn)_動力節(jié)點Java學院整理
動態(tài)代理作為代理模式的一種擴展形式,廣泛應(yīng)用于框架(尤其是基于AOP的框架)的設(shè)計與開發(fā),本文將通過實例來講解Java動態(tài)代理的實現(xiàn)過程2017-08-08
SpringBoot實現(xiàn)發(fā)送短信的示例代碼
這篇文章主要介紹了SpringBoot實現(xiàn)發(fā)送短信的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-04-04
springboot配置內(nèi)存數(shù)據(jù)庫H2教程詳解
這篇文章主要介紹了springboot配置內(nèi)存數(shù)據(jù)庫H2的詳細教程,需要的朋友可以參考下2017-07-07
Java語言描述存儲結(jié)構(gòu)與鄰接矩陣代碼示例
這篇文章主要介紹了Java語言描述存儲結(jié)構(gòu)與鄰接矩陣代碼示例,涉及Java存儲結(jié)構(gòu),鄰接矩陣,鄰接表的介紹與比較,然后分享了鄰接矩陣的Java實現(xiàn)等相關(guān)內(nèi)容,具有一定借鑒價值,需要的朋友可以參考。2017-11-11
解決idea中java出現(xiàn)無效的源發(fā)行版問題
這篇文章主要給大家介紹了關(guān)于解決idea中java出現(xiàn)無效的源發(fā)行版問題的相關(guān)資料,無效的源發(fā)行版是指IntelliJ IDEA無法正確識別和處理的源代碼版本,這可能是由于錯誤的配置、缺少依賴項、不兼容的插件或其他問題導致的,需要的朋友可以參考下2024-01-01
Mybatis-Plus中updateById方法不能更新空值問題解決
本文主要介紹了Mybatis-Plus中updateById方法不能更新空值問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08

