Spring?Bean注冊與注入實現方法詳解
上接【Spring】spring核心思想——IOC和DI
上篇文章結尾簡單介紹了一下使用 XML 注冊 Bean,這篇文章接著介紹一下 XML 注冊 Bean 和使用注解注冊、注入 Bean
1. 邏輯上的 Bean 注冊
2. XML 注冊 Bean 到自建的庫中
上篇文章介紹了使用 XML 三種注冊的三種方式 (直接注入、構造方法注入、set 方法注入),在這里繼續(xù)介紹一下使用工廠方法 和 實例化工廠注冊 Bean
2.1 工廠方法
工廠方法分為靜態(tài)工廠方法和實例工廠方法
使用工廠方法注冊就是調用靜態(tài)工廠方法注冊 Bean
實例化工廠注冊就是調用實例工廠方法注冊 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"/> <!-- 通過已經注冊的 bean 的實例方法注冊,bean 的實例化由我們自己完成--> <bean id="工具bean" class="com.hsq.ioc3.SomeClass"/> <bean id="通過實例化工廠注冊" factory-bean="工具bean" factory-method="instantCreatePerson"/> </beans>
public class SomeClass { // 靜態(tài)方法(可以直接通過類名調用) // 作用:返回一個對象 // 這類方法被稱為工廠方法 public static Person createPerson() { System.out.println("createPerson 被調用"); return new Person(); } public Person instantCreatePerson() { System.out.println("instantCreatePerson 被調用"); return new Person(); } }
public class Person { public Person() { System.out.println("Person 被調用"); } }
通過打印可以清楚的看到兩種方法都成功注冊 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 被調用"); } }
通過打印可以清楚看到,World 對象被成功注冊
4. 使用注解注冊 Bean
使用注解注冊簡而言之就是使用某個注解修飾類或方法,對其進行注冊
使用注解注冊 Bean 是注冊進 Spring 提供的庫,就不需要自建庫了
4.1 注解方式注冊的必要條件
- 要被注解修飾類
- 被注冊的 Bean 要在 XXXApplication 所在包下,否則注冊不會成功
4.2 用到的注解
這幾個注解在 IOC 場景下,沒有區(qū)別,都是將類注冊進 Spring 庫,但在其他場景一般這樣用
@Component:沒有特殊作用時,都可以用
@Controller:SpringMVC中把此注解特殊化了,要求控制器類必須用此注解修飾
@Service:修飾中間數據整合的類
@Repository:修飾數據獲取類
@Configuration:修飾配置類
4.3 @Component注解注入
import org.springframework.stereotype.Component; @Component public class World { public World() { System.out.println("World() 被調用"); } }
@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 調用 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 中(類注冊或者方法注冊都可以)
- 使用構造方法、set 方法、屬性直接注入三種方法注入bean——使用 @Autowired 修飾
import org.springframework.stereotype.Component; @Component public class World { public World() { System.out.println("World() 被調用"); } }
構造方法注入
@Component public class Hello { @Autowired // 這個注解其實可以不寫,但是建議寫上,主要是讓看代碼的人知道我們的 World 對象是被注入的 // 如果有多個構造方法,告訴 Spring,實例化對象是,應該調用哪個 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 注入時的一個坑點() { // 構造方法先執(zhí)行,然后再進行注入(屬性注入 / set 注入) // 所以,構造方法執(zhí)行的時候,注入還沒有發(fā)生,所以還是 null // 所以一般建議使用構造方法注入 System.out.println("注入時的一個坑點(), world = " + this.world); } }
7. 獲取 庫中的對象
ConfigurableApplicationContext context = SpringApplication.run(IocAApplication.class, args); Object world1 = context.getBean("world"); // 根據 id 獲取 bean World world2 = context.getBean(World.class); // 根據類型獲取 bean World world = context.getBean("world", World.class); // 根據 id + 類型獲取 bean
到此這篇關于Spring Bean注冊與注入實現方法詳解的文章就介紹到這了,更多相關Spring Bean注冊與注入內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java動態(tài)代理實現_動力節(jié)點Java學院整理
動態(tài)代理作為代理模式的一種擴展形式,廣泛應用于框架(尤其是基于AOP的框架)的設計與開發(fā),本文將通過實例來講解Java動態(tài)代理的實現過程2017-08-08Mybatis-Plus中updateById方法不能更新空值問題解決
本文主要介紹了Mybatis-Plus中updateById方法不能更新空值問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08