Spring Boot中Bean定义方调用方式解析

 更新时间:2020年07月06日 08:58:48   作者:BarryW  
这篇文章主要介绍了Spring Boot中Bean定义方调用方式解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,想直接使用spring提供的其他对象或者说有一些不需要交给spring管理,但是需要用到spring里的一些对象。如果这是spring框架的独立应用程序,我们通过

ApplicationContextac=newFileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");

这样的方式就可以很轻易的获取我们所需要的对象。

但是往往我们所做的都是WebApplication,这时我们启动spring容器是通过在web.xml文件中配置,这样就不适合使用上面的方式在普通类去获取对象了,因为这样做就相当于加载了两次spring容器,而我们想是否可以通过在启动web服务器的时候,就把Application放在某一个类中,我们通过这个类在获取,这样就可以在普通类获取springbean对象了,让我们接着往下看

下面介绍在SpringBoot中是如何使用的

1.在Spring Boot可以扫描的包下

写的工具类为SpringUtil,实现ApplicationContextAware接口,并加入Component注解,让spring扫描到该bean

springutil:

package me.shijunjie.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtil implements ApplicationContextAware {

  private static ApplicationContext applicationContext;

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    if(SpringUtil.applicationContext == null) {
      SpringUtil.applicationContext = applicationContext;
    }
    System.out.println("---------------------------------------------------------------------");

    System.out.println("---------------------------------------------------------------------");

    System.out.println("---------------me.shijunjie.util.SpringUtil------------------------------------------------------");

    System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========");

    System.out.println("---------------------------------------------------------------------");
  }

  //获取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);
  }
}

为了测试,我们再启动的时候先通过代码方式给spring容器中注入一个bean,入下所示

package me.shijunjie.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import me.shijunjie.entity.Demo2;

@Configuration
public class BeanConfig {
  @Bean(name="testDemo")
  public Demo2 generateDemo() {
    Demo2 demo = new Demo2();
    demo.setId(12345);
    demo.setName("test");
    return demo;
  }
}

然后我们编写测试controller,并从刚才写的springutil中获取这个bean

package me.shijunjie.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import me.shijunjie.util.SpringUtil;

@RestController
@RequestMapping("/application")
public class TestApplicationController {
  
  @RequestMapping("/test1")
  public Object testSpringUtil1() {
    return SpringUtil.getBean("testDemo");
  }
  
}

测试

启动web应用,打开浏览器输入http://localhost:8080/application/test1,测试成功

2不在Spring Boot的扫描包下

这种情况处理起来也很简单,先编写SpringUtil类,同样需要实现接口:ApplicationContextAware,具体编码如下:

package me.shijunjie.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class SpringUtil2 implements ApplicationContextAware {

  private static ApplicationContext applicationContext;

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    if(SpringUtil2.applicationContext == null) {
      SpringUtil2.applicationContext = applicationContext;
    }
    System.out.println("---------------------------------------------------------------------");

    System.out.println("---------------------------------------------------------------------");

    System.out.println("---------------me.shijunjie.util.SpringUtil------------------------------------------------------");

    System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil2.applicationContext+"========");

    System.out.println("---------------------------------------------------------------------");
  }

  //获取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注解,在App.java类中将SpringUtil注解进

package me.shijunjie.controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;

import me.shijunjie.util.SpringUtil2;

@ComponentScan(basePackages={"me.shijunjie"}) // 扫描该包路径下的所有spring组件
/*@EnableJpaRepositories("me.shijunjie.dao") // JPA扫描该包路径下的Repositorie
*//*@EntityScan("me.shijunjie.entity") // 扫描实体类
*/@SpringBootApplication
@EnableScheduling
public class App extends SpringBootServletInitializer{
  @Bean
  public SpringUtil2 getSpringUtil2() {
    return new SpringUtil2();
  }
  
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

测试(使用热部署的需要重启服务器)

启动web应用,打开浏览器输入http://localhost:8080/application/test2,测试成功

除此以外,也可以在App.java中使用@Import进行导入。

package me.shijunjie.controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableScheduling;

import me.shijunjie.util.SpringUtil2;

@ComponentScan(basePackages={"me.shijunjie"}) // 扫描该包路径下的所有spring组件
/*@EnableJpaRepositories("me.shijunjie.dao") // JPA扫描该包路径下的Repositorie
*//*@EntityScan("me.shijunjie.entity") // 扫描实体类
*/@SpringBootApplication
@EnableScheduling
@Import(SpringUtil2.class)
public class App extends SpringBootServletInitializer{
  /*@Bean
  public SpringUtil2 getSpringUtil2() {
    return new SpringUtil2();
  }*/
  
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

跑出结果和上面相同

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot使用SOFA-Lookout监控的方法

    SpringBoot使用SOFA-Lookout监控的方法

    本文介绍SpringBoot使用蚂蚁金服SOFA-Lookout配合Prometheus进行监控,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • Eclipse中Debug时鼠标悬停不能查看变量值解决办法

    Eclipse中Debug时鼠标悬停不能查看变量值解决办法

    这篇文章主要介绍了Eclipse中Debug时鼠标悬停不能查看变量值解决办法,以及分享了一个简单补全代码的方法,还是比较不错的,需要的朋友可以参考下。
    2017-11-11
  • Java中GC与四种引用的关系详解

    Java中GC与四种引用的关系详解

    这篇文章主要介绍了Java中GC与四种引用的关系详解,Java 中一共有 4 种类型的引用 : StrongReference、 SoftReference、 WeakReference 以及 PhantomReference这 4 种类型的引用与 GC 有着密切的关系, 让我们逐一来看它们的定义和使用场景,需要的朋友可以参考下
    2023-09-09
  • MyBatis-Plus UpdateWrapper 使用常见陷阱和解决方案

    MyBatis-Plus UpdateWrapper 使用常见陷阱和解决方案

    MyBatis-Plus是Mybatis的一个增强,简化了Mybatis的开发过程,不仅保持了Mybatis原有的功能,而且在无代码侵略下增加了许多的增强的功能,提供了丰富的CRUD操作,单表的CRUD操作无需编写SQL语句,本文介绍的是UpdateWrapper的常见陷阱和对应的解决方案,感兴趣的朋友一起看看吧
    2024-08-08
  • Java JDK动态代理(AOP)用法及实现原理详解

    Java JDK动态代理(AOP)用法及实现原理详解

    在本篇文章了小编给大家整理的是一篇关于Java JDK动态代理(AOP)用法及实现原理详解内容,有需要的朋友们可以参考学习下。
    2020-10-10
  • 基于Java Socket实现一个简易在线聊天功能(一)

    基于Java Socket实现一个简易在线聊天功能(一)

    这篇文章主要给大家介绍基于Java Socket实现一个简易在线聊天功能(一),分为客户端和服务端两段代码,非常具有参考价值,感兴趣的朋友一起学习吧
    2016-05-05
  • MyBatisX插件之domain文件生成不了问题

    MyBatisX插件之domain文件生成不了问题

    文章描述了在使用MyBatisX插件生成MyBatis的domain文件时遇到的问题,特别是在使用MyBatisX版本1.6.1和MySQL版本8.0.34的情况下,生成的domain文件不完整,作者通过勾选Model选项解决了这个问题,并分享了这一经验,希望能帮助其他遇到类似问题的用户
    2025-01-01
  • java calendar 日期实现不断加一天的代码

    java calendar 日期实现不断加一天的代码

    这篇文章主要介绍了java calendar 日期实现不断加一天的代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Java 中一个类提供一个默认对象的多种方法

    Java 中一个类提供一个默认对象的多种方法

    这篇文章主要介绍了Java 中一个类提供一个默认对象的多种方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Java 轮询锁使用时遇到问题解决方案

    Java 轮询锁使用时遇到问题解决方案

    这篇文章主要介绍了Java 轮询锁使用时遇到问题解决方案,当我们遇到死锁之后,除了可以手动重启程序解决之外,还可以考虑使用顺序锁和轮询锁,但是过程也会遇到一些问题,接下来我们一起进入下面文章了解解决方案,需要的小伙伴可以参考一下
    2022-05-05

最新评论