springboot @Autowired 为空解决方案

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

记录 使用springboot 产生的问题:


一、@Autowired注入为null的几种情况

1.在应用的Filter或Listener中使用了@Autowired ,

原因:因为Filter和Listener加载顺序优先于spring容器初始化实例,所以使用@Autowired肯定为null了~~

解决:用ApplicationContext根据bean名称(注意名称为实现类而不是接口)去获取bean,随便写个工具类即可

2.自己定义的bean没有交给spring管理

目前遇到的应该属于第一种情况,websocket的endpoint的本质应该是一个listener,所以无法使用注入

二、解决方案

spring boot工作流listener监听器获取@Autowired对象Bean为null的解决方案

背景:使用工作流监听器监听流程结束后处理业务,需要使用自己的service方法;

错误:使用@Autowired注入service对象,最终得到的为null;

解决:

1.新建获取bean的类

package com.ww.activiti.config;
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
 
/**
 * 上下文管理
 *
 * @author: Ace Lee
 * @create: 2019-04-22 15:24
 */
@Slf4j
@Configuration
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
 
    private static ApplicationContext applicationContext = null;
 
    /**
     * 取得存储在静态变量中的ApplicationContext.
     */
    public static ApplicationContext getApplicationContext() {
        assertContextInjected();
        return applicationContext;
    }
 
    /**
     * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        log.debug("从SpringContextHolder中取出Bean:" + name);
        assertContextInjected();
        return (T) applicationContext.getBean(name);
    }
 
    /**
     * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
     */
    public static <T> T getBean(Class<T> requiredType) {
        assertContextInjected();
        return applicationContext.getBean(requiredType);
    }
 
    /**
     * 清除SpringContextHolder中的ApplicationContext为Null.
     */
    public static void clearHolder() {
        log.info("清除SpringContextHolder中的ApplicationContext:"
                + applicationContext);
        applicationContext = null;
    }
 
    /**
     * 实现ApplicationContextAware接口, 注入Context到静态变量中.
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
//		logger.debug("注入ApplicationContext到SpringContextHolder:{}", applicationContext);
 
        if (SpringContextHolder.applicationContext != null) {
            log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
        }
 
        SpringContextHolder.applicationContext = applicationContext; // NOSONAR
    }
 
    /**
     * 实现DisposableBean接口, 在Context关闭时清理静态变量.
     */
    @Override
    public void destroy() throws Exception {
        SpringContextHolder.clearHolder();
    }
 
    /**
     * 检查ApplicationContext不为空.
     */
    private static void assertContextInjected() {
        if(applicationContext == null) {
            throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");
        }
    }
}

2.监听器里获取service,使用getBean(XXX.class)

                //这里要注意用@AutoWired注解是获取不到bean的对象
                KafkaSender sender = SpringContextHolder.getBean(KafkaSender.class);
               
                sender.asyncSendMessage("ww_test",proInsId,JacksonUtil.bean2Json(bussData));

总结

参考连接:
链接1https://blog.csdn.net/weixin_38437520/article/details/123589960
链接2https://www.codeleading.com/article/1865853439/

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可能出现这种情况的原因有很多,以下是一些可能的解决方案: 1. 确保在配置文件正确配置了需要自动装配的对象,例如: ``` @Configuration @PropertySource("classpath:application.properties") public class AppConfig { @Autowired private Environment env; @Bean public MyConfig myConfig() { MyConfig config = new MyConfig(); config.setUrl(env.getProperty("my.url")); config.setUsername(env.getProperty("my.username")); config.setPassword(env.getProperty("my.password")); return config; } } ``` 2. 确保配置文件的路径和文件名是正确的,例如: ``` @PropertySource("classpath:application.properties") ``` 这里的classpath表示classpath下的根目录,如果配置文件在子目录下,需要在路径添加相应的目录。 3. 确保项目的classpath正确配置,例如: 在IDEA,可以在项目的“Run/Debug Configurations”查看项目的classpath,确保配置文件在classpath下。 4. 确保需要自动装配的对象类上使用了@Component、@Configuration、@Service等注解,例如: ``` @Component public class MyConfig { private String url; private String username; private String password; // getter and setter methods } ``` 这里使用了@Component注解,表示这是一个Spring组件,可以被自动扫描并装配。 5. 确保使用了正确的@Autowired注解,例如: ``` @Autowired private MyConfig myConfig; ``` 这里使用了@Autowired注解,表示需要自动装配MyConfig对象。 6. 如果使用了多个配置文件,需要确保它们没有冲突,例如: ``` @PropertySources({ @PropertySource("classpath:application.properties"), @PropertySource("classpath:other.properties") }) public class AppConfig { // ... } ``` 这里使用了@PropertySources注解,可以配置多个配置文件。需要确保它们没有相同的属性名,否则会出现冲突。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值