SpringBoot普通类获取spring容器中bean的操作

时间:2021-05-20

前言

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

创建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;@Servicepublic 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;@Componentpublic 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 */@Servicepublic 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)@SpringBootTestpublic 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的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章