当前位置:   article > 正文

SpringBoot静态方法调用Spring容器bean的几种方案_springboot 静态方法中引用bean

springboot 静态方法中引用bean

问题分析

今天一个小伙伴和我说@Autowired 注入的Bean为null值,经过一番沟通后,我发现原来他需要在静态方法中调用容器Bean,大致将代码贴出来给大家看看:

//模拟错误的使用方式
@Autowired
private static RedisUtil redisUtilBean;

public static String getMsgByRedis(){
redisUtilBean.get("xxx")  //这里redisUtilBean一定会是NULL值
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

为什么会出现这种情况?原因是Spring容器的依赖注入是依赖set方法,而set方法是实例对象的方法,注入依赖时是无法注入静态成员变量的,在调用的时候依赖的Bean才会为null;

解决方案一

使用@PostConstruct注解,

    @Autowired
    private RedisUtil redisUtilBean;
    
    //由于静态方法无法使用注入的Bean 定义静态变量
    private static RedisUtil redisUtil;

    //当容器实例化当前受管Bean时@PostConstruct注解的方法会被自动触发,借此来实现静态变量初始化
    @PostConstruct
    public void init(){
        this.redisUtil = redisUtilBean;
    }
    
	public static String getMsgByRedis(){
		redisUtil.get("xxx")  //这里可以正常使用
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

解决方案二

利用springboot的启动类中,SpringApplication.run() 方法返回的是一个ConfigurableApplicationContext对象通过定义static变量ConfigurableApplicationContext,利用容器的getBean方法获得依赖对象;

@SpringBootApplication
@EnableTransactionManagement
public class Application {
	//定义静态的ApplicationContext
    public static ConfigurableApplicationContext applicationContext;
    public static void main(String[] args) {
        applicationContext = SpringApplication.run(Application.class, args);
    }
}

	//调用  注意Application是我们SpringBoot的启动类
	public static String getMsgByRedis(){
		Application.applicationContext..getBean(RedisUtil .class).get("xxx") 
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

解决方案三

在我们以前SpringMVC中常用的工具类,通过实现ApplicationContextAware接口,网上也很多这里就把工具类贴出来即可;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.toher.common.utils.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext.
 *
 * @author 李怀明
 * @version 2017-01-02
 */
@Component
public class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    //实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextHolder.applicationContext = applicationContext;
    }

    //取得存储在静态变量中的ApplicationContext.
    public static ApplicationContext getApplicationContext() {
        checkApplicationContext();
        return applicationContext;
    }

    //从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        checkApplicationContext();
        return (T) applicationContext.getBean(name);
    }

    //从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
    //如果有多个Bean符合Class, 取出第一个.
    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> clazz) {
        checkApplicationContext();
        @SuppressWarnings("rawtypes")
        Map beanMaps = applicationContext.getBeansOfType(clazz);
        if (beanMaps != null && !beanMaps.isEmpty()) {
            return (T) beanMaps.values().iterator().next();
        } else {
            return null;
        }
    }

    private static void checkApplicationContext() {
        if (applicationContext == null) {
            throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
        }
    }

    public static HttpServletRequest getRequest() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        } catch (Exception e) {
            return null;
        }
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

调用方法:

RedisUtil redisUtil= (RedisUtil) SpringContextHolder.getBean(RedisUtil.class);
  • 1

结语

以上就是博主整理的几个解决方案,希望能帮助到大家~ 谢谢~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/798426
推荐阅读
相关标签
  

闽ICP备14008679号