SpringBoot普通類(lèi)獲取spring容器中bean的操作
前言
在spring框架中,是無(wú)法在普通類(lèi)中通過(guò)注解注入實(shí)例的,因?yàn)閟ping框架在啟動(dòng)的時(shí)候,就會(huì)將標(biāo)明交給spring容器管理的類(lèi)進(jìn)行實(shí)例化,并梳理他們彼此的依賴(lài)關(guān)系,進(jìn)行注入,沒(méi)有交給spring容器管理的普通類(lèi),是不會(huì)進(jìn)行注入的,即使你使用了注入的相關(guān)注解。這個(gè)時(shí)候,如果我們需要在普通類(lèi)中獲取spring容器中的實(shí)例,就需要一些特定的方法,這里將整理一下如何在springboot中實(shí)現(xiàn)這樣的方法。
創(chuàng)建springboot工程demo
項(xiàng)目結(jié)構(gòu)圖示

項(xiàng)目結(jié)構(gòu)說(shuō)明
service包下為demo接口和實(shí)現(xiàn)類(lèi),添加@Service注解,標(biāo)明交由spring框架管理實(shí)例。
test包下為測(cè)試用的普通類(lèi),測(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)類(lèi)
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方法的返回值賦值給工具類(lèi)中的靜態(tài)變量
BeanUtil.applicationContext = applicationContext;
//測(cè)試獲取已經(jīng)實(shí)例化的接口bean,執(zhí)行bean中方法
new Test().test();
}
}
測(cè)試效果

可以看到,test方法應(yīng)成功獲取DemoService接口實(shí)例,這里總結(jié)的是springboot工程在普通類(lèi)獲取sping容器中實(shí)例的方法,其原理和傳統(tǒng)方法其實(shí)都是一樣的,獲取上下文環(huán)境,從上下文環(huán)境中拿到spring容器管理的實(shí)例。
補(bǔ)充知識(shí):SpringBoot獲取Bean
一種最簡(jiǎn)單的方法是實(shí)現(xiàn)ApplicationContextAware類(lèi)來(lái)獲取容器中的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;
}
//通過(guò)name獲取 Bean.
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
//通過(guò)class獲取Bean.
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
//通過(guò)name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
我們可以通過(guò)bean的名稱(chēng)、bean的類(lèi)型或者bean的名稱(chēng)+類(lèi)型來(lái)獲取容器中的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普通類(lèi)獲取spring容器中bean的操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot 如何使用jedis連接Redis數(shù)據(jù)庫(kù)
這篇文章主要介紹了springboot 使用jedis連接Redis數(shù)據(jù)庫(kù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
啟動(dòng) Eclipse 彈出 Failed to load the JNI shared library jvm.dll
這篇文章主要介紹了有時(shí)候,新電腦上回碰到打開(kāi)Eclipse時(shí),彈出提示“Failed to load the JNI shared library jvm.dll”錯(cuò)誤,這里給大家分享解決方案2016-08-08
java數(shù)據(jù)結(jié)構(gòu)基礎(chǔ):稀疏數(shù)組
今天帶大家了解一下Java稀疏數(shù)組的相關(guān)知識(shí),文中有非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下2021-08-08
Java練習(xí)之潛艇小游戲的實(shí)現(xiàn)
這篇文章主要和大家分享一個(gè)Java小練習(xí)——利用Java編寫(xiě)一個(gè)潛艇小游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-03-03
SpringSecurity中PasswordEncoder的使用
密碼存儲(chǔ)和加密是非常重要的,本文主要介紹了SpringSecurity中PasswordEncoder的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01
Spring?Boot?集成?MyBatis?全面講解(最新推薦)
MyBatis 是一款優(yōu)秀的持久層框架,與 Spring Boot 集成后可以大大簡(jiǎn)化開(kāi)發(fā)流程,本文將全面講解如何在 Spring Boot 中集成 MyBatis,包括環(huán)境配置、基礎(chǔ)操作、高級(jí)功能和最佳實(shí)踐,需要的朋友可以參考下2024-12-12
使用Java實(shí)現(xiàn)動(dòng)態(tài)生成MySQL數(shù)據(jù)庫(kù)
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)動(dòng)態(tài)生成MySQL數(shù)據(jù)庫(kù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02
Java 如何同時(shí)返回多個(gè)不同類(lèi)型
這篇文章主要介紹了Java 同時(shí)返回多個(gè)不同類(lèi)型的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Spring Boot 整合 Druid 并開(kāi)啟監(jiān)控的操作方法
本文介紹了如何在SpringBoot項(xiàng)目中引入和配置Druid數(shù)據(jù)庫(kù)連接池,并開(kāi)啟其監(jiān)控功能,通過(guò)添加依賴(lài)、配置數(shù)據(jù)源、開(kāi)啟監(jiān)控、自定義配置以及訪問(wèn)監(jiān)控頁(yè)面,開(kāi)發(fā)者可以有效提高數(shù)據(jù)庫(kù)訪問(wèn)效率并監(jiān)控連接池狀態(tài),感興趣的朋友跟隨小編一起看看吧2025-01-01

