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

 更新时间:2020年09月29日 11:03:13   作者:hgzheng  
这篇文章主要介绍了SpringBoot普通类获取spring容器中bean的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

前言

在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;

@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的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • springboot 如何使用jedis连接Redis数据库

    springboot 如何使用jedis连接Redis数据库

    这篇文章主要介绍了springboot 使用jedis连接Redis数据库的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 启动 Eclipse 弹出 Failed to load the JNI shared library jvm.dll 错误的解决方法

    启动 Eclipse 弹出 Failed to load the JNI shared library jvm.dll

    这篇文章主要介绍了有时候,新电脑上回碰到打开Eclipse时,弹出提示“Failed to load the JNI shared library jvm.dll”错误,这里给大家分享解决方案
    2016-08-08
  • java数据结构基础:稀疏数组

    java数据结构基础:稀疏数组

    今天带大家了解一下Java稀疏数组的相关知识,文中有非常详细的介绍及代码示例,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-08-08
  • Java练习之潜艇小游戏的实现

    Java练习之潜艇小游戏的实现

    这篇文章主要和大家分享一个Java小练习——利用Java编写一个潜艇小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-03-03
  • SpringSecurity中PasswordEncoder的使用

    SpringSecurity中PasswordEncoder的使用

    密码存储和加密是非常重要的,本文主要介绍了SpringSecurity中PasswordEncoder的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • Spring Boot 集成 MyBatis 全面讲解(最新推荐)

    Spring Boot 集成 MyBatis 全面讲解(最新推荐)

    MyBatis 是一款优秀的持久层框架,与 Spring Boot 集成后可以大大简化开发流程,本文将全面讲解如何在 Spring Boot 中集成 MyBatis,包括环境配置、基础操作、高级功能和最佳实践,需要的朋友可以参考下
    2024-12-12
  • 使用Java实现动态生成MySQL数据库

    使用Java实现动态生成MySQL数据库

    这篇文章主要为大家详细介绍了如何使用Java实现动态生成MySQL数据库,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-02-02
  • Java 如何同时返回多个不同类型

    Java 如何同时返回多个不同类型

    这篇文章主要介绍了Java 同时返回多个不同类型的方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • SWT(JFace)小制作 FileBrowser文件浏览

    SWT(JFace)小制作 FileBrowser文件浏览

    SWT(JFace)小制作 FileBrowser文件浏览
    2009-06-06
  • Spring Boot 整合 Druid 并开启监控的操作方法

    Spring Boot 整合 Druid 并开启监控的操作方法

    本文介绍了如何在SpringBoot项目中引入和配置Druid数据库连接池,并开启其监控功能,通过添加依赖、配置数据源、开启监控、自定义配置以及访问监控页面,开发者可以有效提高数据库访问效率并监控连接池状态,感兴趣的朋友跟随小编一起看看吧
    2025-01-01

最新评论