SpringBoot使用@Autowired注入静态变量报空指针异常

简介: 类变量(用static修饰)是属于类的,在spring容器中都是实例化对象。当我们使用静态变量或静态方法时,不需要new出来一个类的实例化对象,所以使用@Autowired修饰一个静态变量时,该静态变量并没有真正实例化成一个对象,因此该静态变量为null,不能使用 @Autowired来注入静态变量。

问题:

在编写发送邮件工具类MailUtil时,直接使用@Autowired静态注入JavaMailSender,运行时报空指针异常

@Component
public class MailUtil {

    @Autowired
    private static JavaMailSender mailSender;
}

原因分析:

类变量(用static修饰)是属于类的,在spring容器中都是实例化对象。当我们使用静态变量或静态方法时,不需要new出来一个类的实例化对象,所以使用@Autowired修饰一个静态变量时,该静态变量并没有真正实例化成一个对象,因此该静态变量为null,不能使用 @Autowired来注入静态变量。

解决方案:

代码如下:

@Component
public class MailUtil {
    
    @Autowired
    private JavaMailSender JavaMailSender;

    private static JavaMailSender mailSender;

    @PostConstruct
    public void init(){

        mailSender = JavaMailSender;
        System.out.println("mailSender初始化");
    }
}

也可以先加载ApplicationContext (spring上下文环境)

@Component
public class MailUtil {

    @Autowired
    private ApplicationContext applicationContext;

    private static JavaMailSender mailSender;

    @PostConstruct
    public void init(){

        MailUtil.mailSender = applicationContext.getBean(JavaMailSender.class);
        System.out.println("mailSender初始化");
    }
}

实现原理:

  1. 类名上使用 @Component 使当前类成为一个bean对象,加入 spring 的管理中。(或者使用 @service)
  2. 先将需要调用的对象注入进来
  3. 重新创建一个所需对象的 static 变量
  4. 写个 @PostConstruct 注解的方法,在这个方法里,初始化在第3步创建的 static 变量,将之前注入的对象赋值给它
  5. 静态方法中就能够直接进行调用第3步创建的静态变量

关于@PostConstruct

  1. @PostConstruct注解的方法在项目启动的时候执行这个方法,也可以理解为在spring容器启动的时候执行,可作为一些数据的常规化加载,比如数据字典之类的。

被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,修饰的方法会在构造函数之后,init()方法之前运行

  1. 执行顺序:Constructor >> @Autowired >> @PostConstruct
  2. 需要注意的是,注解会影响到服务器的启动速度。服务器在启动时候会遍历Web 应用的WEB-INF/classes下的所有class文件与WEB-INF/lib下的所有jar文件,以检查哪些类使用了注解。如果应用程序中没有 使用任何注解,可以在Web.xml中设置的metadata-complete属性为true
目录
相关文章
|
2月前
|
Java
springboot字段注入@value细节
springboot字段注入@value细节
25 1
|
2月前
|
Java
springboot自动注入避坑
springboot自动注入避坑
24 1
|
2月前
|
Java Linux 程序员
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
|
3月前
|
Java Spring 容器
SpringBoot 使用Quartz执行定时任务对象时无法注入Bean问题
SpringBoot 使用Quartz执行定时任务对象时无法注入Bean问题
123 1
|
3月前
|
JSON Java 数据库连接
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
62 1
|
5天前
|
SQL JavaScript 前端开发
vue中使用分页组件、将从数据库中查询出来的数据分页展示(前后端分离SpringBoot+Vue)
这篇文章详细介绍了如何在Vue.js中使用分页组件展示从数据库查询出来的数据,包括前端Vue页面的表格和分页组件代码,以及后端SpringBoot的控制层和SQL查询语句。
vue中使用分页组件、将从数据库中查询出来的数据分页展示(前后端分离SpringBoot+Vue)
|
1天前
|
JavaScript Java Maven
毕设项目&课程设计&毕设项目:springboot+vue实现的在线求职管理平台(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和Vue.js实现的在线求职平台。该平台采用了前后端分离的架构,使用Spring Boot作为后端服务
毕设项目&课程设计&毕设项目:springboot+vue实现的在线求职管理平台(含教程&源码&数据库数据)
|
1天前
|
Java 微服务 Spring
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
文章介绍了如何利用Spring Cloud Alibaba快速构建大型电商系统的分布式微服务,包括服务限流降级等主要功能的实现,并通过注解和配置简化了Spring Cloud应用的接入和搭建过程。
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
|
1天前
|
NoSQL JavaScript 前端开发
SpringBoot+Vue实现校园二手系统。前后端分离技术【完整功能介绍+实现详情+源码】
文章介绍了如何使用SpringBoot和Vue实现一个校园二手系统,采用前后端分离技术。系统具备完整的功能,包括客户端和管理员端的界面设计、个人信息管理、商品浏览和交易、订单处理、公告发布等。技术栈包括Vue框架、ElementUI、SpringBoot、Mybatis-plus和Redis。文章还提供了部分源代码,展示了前后端的请求接口和Redis验证码功能实现,以及系统重构和模块化设计的一些思考。
SpringBoot+Vue实现校园二手系统。前后端分离技术【完整功能介绍+实现详情+源码】
|
4天前
|
前端开发 JavaScript Java
SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))
这篇文章详细介绍了在SpringBoot+Vue项目中实现表单和图片上传的完整流程,包括前端上传、后端接口处理、数据库保存图片路径,以及前端图片回显的方法,同时探讨了图片资源映射、token验证、过滤器配置等相关问题。