SpringBoot普通類獲取spring容器中bean的操作
前言
在spring框架中,是無法在普通類中通過注解注入實例的,因為sping框架在啟動的時候,就會將標明交給spring容器管理的類進行實例化,并梳理他們彼此的依賴關系,進行注入,沒有交給spring容器管理的普通類,是不會進行注入的,即使你使用了注入的相關注解。這個時候,如果我們需要在普通類中獲取spring容器中的實例,就需要一些特定的方法,這里將整理一下如何在springboot中實現(xiàn)這樣的方法。
創(chuàng)建springboot工程demo
項目結構圖示

項目結構說明
service包下為demo接口和實現(xiàn)類,添加@Service注解,標明交由spring框架管理實例。
test包下為測試用的普通類,測試獲取實例的方法。
utils包下為自定義的獲取spring容器中實例的方法。
工程代碼
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注解標明了此實例交由spring容器管理
test
package com.demo.test;
import com.demo.service.IDemoService;
import com.demo.utils.BeanUtil;
public class Test {
public void test(){
//獲取已經(jīng)實例化的接口bean
IDemoService bean = BeanUtil.getBean(IDemoService.class);
//執(zhí)行bean中方法
String demo = bean.demo();
//輸出結果
System.out.println(demo);
}
}
utils
package com.demo.utils;
import org.springframework.context.ConfigurableApplicationContext;
public class BeanUtil {
//將管理上下文的applicationContext設置成靜態(tài)變量,供全局調(diào)用
public static ConfigurableApplicationContext applicationContext;
//定義一個獲取已經(jīng)實例化bean的方法
public static <T> T getBean(Class<T> c){
return applicationContext.getBean(c);
}
}
啟動類
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;
//測試獲取已經(jīng)實例化的接口bean,執(zhí)行bean中方法
new Test().test();
}
}
測試效果

可以看到,test方法應成功獲取DemoService接口實例,這里總結的是springboot工程在普通類獲取sping容器中實例的方法,其原理和傳統(tǒng)方法其實都是一樣的,獲取上下文環(huán)境,從上下文環(huán)境中拿到spring容器管理的實例。
補充知識:SpringBoot獲取Bean
一種最簡單的方法是實現(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。
默認情況下,Spring容器中的bean是單例的,為此我做了一個測試,我創(chuàng)建了兩個bean,一個是默認的,一個是我指定多例的:
import org.springframework.stereotype.Service;
/**
* 這是一個單例的bean
*/
@Service
public class BeanSingletonService {
}
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
/**
* 這是一個多例的bean
*/
@Service
@Scope("prototype")
public class BeanPrototypeService {
}
驗證下我的想法:
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));
}
}

從結果中可以看到默認的BeanSingletonService 這個bean是單例的,兩個對象完全相等,而我指定的BeanPrototypeService 這個bean則是多例的,兩個bean不相同。
以上這篇SpringBoot普通類獲取spring容器中bean的操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
springboot 如何使用jedis連接Redis數(shù)據(jù)庫
這篇文章主要介紹了springboot 使用jedis連接Redis數(shù)據(jù)庫的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
啟動 Eclipse 彈出 Failed to load the JNI shared library jvm.dll
這篇文章主要介紹了有時候,新電腦上回碰到打開Eclipse時,彈出提示“Failed to load the JNI shared library jvm.dll”錯誤,這里給大家分享解決方案2016-08-08
SpringSecurity中PasswordEncoder的使用
密碼存儲和加密是非常重要的,本文主要介紹了SpringSecurity中PasswordEncoder的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-01-01
Spring?Boot?集成?MyBatis?全面講解(最新推薦)
MyBatis 是一款優(yōu)秀的持久層框架,與 Spring Boot 集成后可以大大簡化開發(fā)流程,本文將全面講解如何在 Spring Boot 中集成 MyBatis,包括環(huán)境配置、基礎操作、高級功能和最佳實踐,需要的朋友可以參考下2024-12-12
使用Java實現(xiàn)動態(tài)生成MySQL數(shù)據(jù)庫
這篇文章主要為大家詳細介紹了如何使用Java實現(xiàn)動態(tài)生成MySQL數(shù)據(jù)庫,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2024-02-02
Spring Boot 整合 Druid 并開啟監(jiān)控的操作方法
本文介紹了如何在SpringBoot項目中引入和配置Druid數(shù)據(jù)庫連接池,并開啟其監(jiān)控功能,通過添加依賴、配置數(shù)據(jù)源、開啟監(jiān)控、自定義配置以及訪問監(jiān)控頁面,開發(fā)者可以有效提高數(shù)據(jù)庫訪問效率并監(jiān)控連接池狀態(tài),感興趣的朋友跟隨小編一起看看吧2025-01-01

