如何通过SpringBoot在普通类中获取Spring容器中的Bean?

2026-05-16 03:231阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计980个文字,预计阅读时间需要4分钟。

如何通过SpringBoot在普通类中获取Spring容器中的Bean?

前言:在Spring框架中,无法在普通类中通过注解注入实例,因为Spring框架在启动时会将标记的类实例化,并管理它们的依赖关系。

前言

在spring框架中,是无法在普通类中通过注解注入实例的,因为sping框架在启动的时候,就会将标明交给spring容器管理的类进行实例化,并梳理他们彼此的依赖关系,进行注入,没有交给spring容器管理的普通类,是不会进行注入的,即使你使用了注入的相关注解。这个时候,如果我们需要在普通类中获取spring容器中的实例,就需要一些特定的方法,这里将整理一下如何在springboot中实现这样的方法。

如何通过SpringBoot在普通类中获取Spring容器中的Bean?

创建springboot工程demo

项目结构图示

项目结构说明

service包下为demo接口和实现类,添加@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(){ //获取已经实例化的接口bean IDemoService bean = BeanUtil.getBean(IDemoService.class); //执行bean中方法 String demo = bean.demo(); //输出结果 System.out.println(demo); } }

utils

package com.demo.utils; import org.springframework.context.ConfigurableApplicationContext; public class BeanUtil { //将管理上下文的applicationContext设置成静态变量,供全局调用 public static ConfigurableApplicationContext applicationContext; //定义一个获取已经实例化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方法的返回值赋值给工具类中的静态变量 BeanUtil.applicationContext = applicationContext; //测试获取已经实例化的接口bean,执行bean中方法 new Test().test(); } }

测试效果

可以看到,test方法应成功获取DemoService接口实例,这里总结的是springboot工程在普通类获取sping容器中实例的方法,其原理和传统方法其实都是一样的,获取上下文环境,从上下文环境中拿到spring容器管理的实例。

补充知识:SpringBoot获取Bean

一种最简单的方法是实现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是单例的,为此我做了一个测试,我创建了两个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的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持易盾网络。

本文共计980个文字,预计阅读时间需要4分钟。

如何通过SpringBoot在普通类中获取Spring容器中的Bean?

前言:在Spring框架中,无法在普通类中通过注解注入实例,因为Spring框架在启动时会将标记的类实例化,并管理它们的依赖关系。

前言

在spring框架中,是无法在普通类中通过注解注入实例的,因为sping框架在启动的时候,就会将标明交给spring容器管理的类进行实例化,并梳理他们彼此的依赖关系,进行注入,没有交给spring容器管理的普通类,是不会进行注入的,即使你使用了注入的相关注解。这个时候,如果我们需要在普通类中获取spring容器中的实例,就需要一些特定的方法,这里将整理一下如何在springboot中实现这样的方法。

如何通过SpringBoot在普通类中获取Spring容器中的Bean?

创建springboot工程demo

项目结构图示

项目结构说明

service包下为demo接口和实现类,添加@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(){ //获取已经实例化的接口bean IDemoService bean = BeanUtil.getBean(IDemoService.class); //执行bean中方法 String demo = bean.demo(); //输出结果 System.out.println(demo); } }

utils

package com.demo.utils; import org.springframework.context.ConfigurableApplicationContext; public class BeanUtil { //将管理上下文的applicationContext设置成静态变量,供全局调用 public static ConfigurableApplicationContext applicationContext; //定义一个获取已经实例化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方法的返回值赋值给工具类中的静态变量 BeanUtil.applicationContext = applicationContext; //测试获取已经实例化的接口bean,执行bean中方法 new Test().test(); } }

测试效果

可以看到,test方法应成功获取DemoService接口实例,这里总结的是springboot工程在普通类获取sping容器中实例的方法,其原理和传统方法其实都是一样的,获取上下文环境,从上下文环境中拿到spring容器管理的实例。

补充知识:SpringBoot获取Bean

一种最简单的方法是实现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是单例的,为此我做了一个测试,我创建了两个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的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持易盾网络。