SpringBoot中的静态方法如何获取bean

本文介绍了在SpringBoot中静态方法获取bean的三种方法:1) 使用@PostConstruct注解;2) 在启动类中定义静态ApplicationContext;3) 创建获取bean的工具类并手动注入ApplicationContext。

目录

SpringBoot中的静态方法获取bean的三种方案

方式一 注解@PostConstruct

方式二 启动类ApplicationContext

方式三 手动注入ApplicationContext


前言:在开发过程中,当在静态方法内调用bean的时候会遇到以下类型错误,均是使用不当造成的

ps:不看错误可以直接跳转标题“SpringBoot中的静态方法获取bean的三种方案

错误1:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderDetailInfoController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderDetailServiceFactory': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'WJOrderDetailService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shopInfoHelper': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'wareInfoHelper': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'wareButtonHelper' defined in URL [jar:file:xxx/WEB-INF/lib/xxx-1.0-SNAPSHOT.jar!/com/xxx/mti/order/web/service/helpers/ware/WareButtonHelper.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: @Resource annotation is not supported on static fields
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:324) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]

原因:提示“@Resource annotation is not supported on static fields”,这个错误是因为在Java中,@Resource注解不支持用在静态字段上。@Resource注解通常用于依赖注入,而不支持用在静态字段上。

错误2:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderDetailInfoController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderDetailServiceFactory': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'WJOrderDetailService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shopInfoHelper': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'wareInfoHelper': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'wareButtonHelper': Invocation of init method failed; nested exception is java.lang.NullPointerException
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:324) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE] 

原因:由于 @Resource注解不支持用在静态变量上,便尝试使用@Autowired注解来实现bean注入,缺发现在Springframework里,我们不能@Autowired一个静态变量,使之成为一个Spring bean,从而出现NPE(java.lang.NullPointerException: null异常)异常。因为当类加载器加载静态变量时,Spring上下文尚未加载。所以类加载器不会在bean中正确注入静态类,并且会失败。

那么如何在springboot的静态方法使用bean呢?以下提供三种解决方案


SpringBoot中的静态方法获取bean的三种方案

方式一 注解@PostConstruct

方式二 启动类ApplicationContext

方式三 手动注入ApplicationContext

方式一 注解@PostConstruct

@Componetn
public class ASerivce {    
    @Resource
    private ConfigService configService;

    private static ConfigService staticConfigService;

    @PostConstruct
    public void init(){
        staticConfigService = configService;
    }

    public static void test(){
        staticConfigService.xxx();//等同于configService.xxx()
    }    
}

注解@PostConstruct说明:

@PostConstruct 注解用于在对象初始化之后执行特定的初始化操作。这个注解通常与依赖注入框架(如Spring)一起使用,以确保在依赖注入完成后立即执行初始化逻辑。

适用场景包括:

  1. 执行需要依赖注入完成后才能进行的初始化逻辑。
  2. 在对象创建后进行一些必要的设置或准备工作。

例如,在使用Spring框架时,可以在一个方法上添加 @PostConstruct 注解,以确保在依赖注入完成后执行特定的初始化逻辑,如数据加载、资源分配等操作。

注:使用PostConstruct需要执行以下标准

  • 该方法不得有任何参数,除非是在 EJB 拦截器 (interceptor) 的情况下,根据 EJB 规范的定义,在这种情况下它将带有一个 InvocationContext 对象 ;
  • 该方法的返回类型必须为 void;
  • 该方法不得抛出已检查异常;
  • 应用 PostConstruct 的方法可以是 public、protected、package private 或 private;
  • 除了应用程序客户端之外,该方法不能是 static;
  • 该方法可以是 final;
  • 如果该方法抛出未检查异常,那么不得将类放入服务中,除非是能够处理异常并可从中恢复的 EJB。

方式二 启动类ApplicationContext

实现方式:在springboot的启动类中,定义static变量ApplicationContext,利用容器的getBean方法获得依赖对象

@SpringBootApplication
public class Application {
    public static ConfigurableApplicationContext ac;
    public static void main(String[] args) {
       ac = SpringApplication.run(Application.class, args);
    } 
}

调用:

@Componetn
public class BSerivce {
    public static void test(){
        ConfigService configService = Application.ac.getBean(ConfigService.class);
        configService.xxx();
    }    
}

注:Application类就是我们springboot项目的启动类

方式三 手动注入ApplicationContext

优先创建获取bean的工具类

@Component
public class StaticMethodGetBean<T> implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        StaticMethodGetBean.applicationContext = applicationContext;
    }
 
    public static <T> T  getBean(Class<T> clazz) {
        return applicationContext != null?applicationContext.getBean(clazz):null;
    }
}

调用:

@Componetn
public class CSerivce {
    public static void test(){
        ConfigService configService = StaticMethodGetBean.getBean(ConfigService.class);
        configService.xxx();
    }    
}

----end----

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值