SpringBoot普通類獲取spring容器中bean的操作
前言
在spring框架中,是無法在普通類中通過注解注入實(shí)例的,因?yàn)閟ping框架在啟動(dòng)的時(shí)候,就會(huì)將標(biāo)明交給spring容器管理的類進(jìn)行實(shí)例化,并梳理他們彼此的依賴關(guān)系,進(jìn)行注入,沒有交給spring容器管理的普通類,是不會(huì)進(jìn)行注入的,即使你使用了注入的相關(guān)注解。這個(gè)時(shí)候,如果我們需要在普通類中獲取spring容器中的實(shí)例,就需要一些特定的方法,這里將整理一下如何在springboot中實(shí)現(xiàn)這樣的方法。
創(chuàng)建springboot工程demo
項(xiàng)目結(jié)構(gòu)圖示
項(xiàng)目結(jié)構(gòu)說明
service包下為demo接口和實(shí)現(xiàn)類,添加@Service注解,標(biāo)明交由spring框架管理實(shí)例。
test包下為測(cè)試用的普通類,測(cè)試獲取實(shí)例的方法。
utils包下為自定義的獲取spring容器中實(shí)例的方法。
工程代碼
service
package com.demo.service; public interface IDemoService { String demo(); }
package com.demo.service.impl; import com.demo.service.IDemoService; import org.springframework.stereotype.Service; @Service public class DemoServiceImpl implements IDemoService { @Override public String demo() { return "Hello World"; } }
@Service注解標(biāo)明了此實(shí)例交由spring容器管理
test
package com.demo.test; import com.demo.service.IDemoService; import com.demo.utils.BeanUtil; public class Test { public void test(){ //獲取已經(jīng)實(shí)例化的接口bean IDemoService bean = BeanUtil.getBean(IDemoService.class); //執(zhí)行bean中方法 String demo = bean.demo(); //輸出結(jié)果 System.out.println(demo); } }
utils
package com.demo.utils; import org.springframework.context.ConfigurableApplicationContext; public class BeanUtil { //將管理上下文的applicationContext設(shè)置成靜態(tài)變量,供全局調(diào)用 public static ConfigurableApplicationContext applicationContext; //定義一個(gè)獲取已經(jīng)實(shí)例化bean的方法 public static <T> T getBean(Class<T> c){ return applicationContext.getBean(c); } }
啟動(dòng)類
package com.demo; import com.demo.test.Test; import com.demo.utils.BeanUtil; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication() public class DemoApplication { public static void main(String[] args) { //run方法的返回值ConfigurableApplicationContext繼承了ApplicationContext上下文接口 ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args); //將run方法的返回值賦值給工具類中的靜態(tài)變量 BeanUtil.applicationContext = applicationContext; //測(cè)試獲取已經(jīng)實(shí)例化的接口bean,執(zhí)行bean中方法 new Test().test(); } }
測(cè)試效果
可以看到,test方法應(yīng)成功獲取DemoService接口實(shí)例,這里總結(jié)的是springboot工程在普通類獲取sping容器中實(shí)例的方法,其原理和傳統(tǒng)方法其實(shí)都是一樣的,獲取上下文環(huán)境,從上下文環(huán)境中拿到spring容器管理的實(shí)例。
補(bǔ)充知識(shí):SpringBoot獲取Bean
一種最簡(jiǎn)單的方法是實(shí)現(xiàn)ApplicationContextAware類來獲取容器中的bean:
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } //獲取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } //通過name獲取 Bean. public static Object getBean(String name) { return getApplicationContext().getBean(name); } //通過class獲取Bean. public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } //通過name,以及Clazz返回指定的Bean public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }
我們可以通過bean的名稱、bean的類型或者bean的名稱+類型來獲取容器中的bean。
默認(rèn)情況下,Spring容器中的bean是單例的,為此我做了一個(gè)測(cè)試,我創(chuàng)建了兩個(gè)bean,一個(gè)是默認(rèn)的,一個(gè)是我指定多例的:
import org.springframework.stereotype.Service; /** * 這是一個(gè)單例的bean */ @Service public class BeanSingletonService { }
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; /** * 這是一個(gè)多例的bean */ @Service @Scope("prototype") public class BeanPrototypeService { }
驗(yàn)證下我的想法:
import com.xqnode.learning.common.config.SpringContextUtil; import com.xqnode.learning.service.BeanPrototypeService; import com.xqnode.learning.service.BeanSingletonService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class LearningApplicationTests { @Test public void contextLoads() { BeanSingletonService s1 = SpringContextUtil.getBean(BeanSingletonService.class); BeanSingletonService s2 = SpringContextUtil.getBean(BeanSingletonService.class); BeanPrototypeService p1 = SpringContextUtil.getBean(BeanPrototypeService.class); BeanPrototypeService p2 = SpringContextUtil.getBean(BeanPrototypeService.class); System.out.println("s1==s2: " + s1.equals(s2)); System.out.println("p1==p2: " + p1.equals(p2)); } }
從結(jié)果中可以看到默認(rèn)的BeanSingletonService 這個(gè)bean是單例的,兩個(gè)對(duì)象完全相等,而我指定的BeanPrototypeService 這個(gè)bean則是多例的,兩個(gè)bean不相同。
以上這篇SpringBoot普通類獲取spring容器中bean的操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
多個(gè)SpringBoot項(xiàng)目采用redis實(shí)現(xiàn)Session共享功能
這篇文章主要介紹了多個(gè)SpringBoot項(xiàng)目采用redis實(shí)現(xiàn)Session共享,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09java Array和Arrays的區(qū)別總結(jié)
在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于java Array和Arrays的區(qū)別總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2021-03-03基于Java編寫第一個(gè)區(qū)塊鏈項(xiàng)目
區(qū)塊鏈?zhǔn)欠植际綌?shù)據(jù)存儲(chǔ)、點(diǎn)對(duì)點(diǎn)傳輸、共識(shí)機(jī)制、加密算法等計(jì)算機(jī)技術(shù)的新型應(yīng)用模式,下面這篇文章主要給大家介紹了基于Java實(shí)現(xiàn)區(qū)塊鏈的相關(guān)資料,需要的朋友可以參考下2021-08-08在Java Spring框架中使用的設(shè)計(jì)模式有哪些
面試中常會(huì)被問道Spring框架使用了哪些設(shè)計(jì)模式?關(guān)于這個(gè)問題本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09Java實(shí)現(xiàn)深度優(yōu)先搜索(DFS)和廣度優(yōu)先搜索(BFS)算法
深度優(yōu)先搜索(DFS)和廣度優(yōu)先搜索(BFS)是兩種基本的圖搜索算法,可用于圖的遍歷、路徑搜索等問題。DFS采用棧結(jié)構(gòu)實(shí)現(xiàn),從起點(diǎn)開始往深處遍歷,直到找到目標(biāo)節(jié)點(diǎn)或遍歷完整個(gè)圖;BFS采用隊(duì)列結(jié)構(gòu)實(shí)現(xiàn),從起點(diǎn)開始往廣處遍歷,直到找到目標(biāo)節(jié)點(diǎn)或遍歷完整個(gè)圖2023-04-04