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

导读:本篇文章讲解 SpringBoot使用@Autowired注入静态变量报空指针异常,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

问题:

在编写发送邮件工具类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()方法之前运行

  2. 执行顺序:Constructor >> @Autowired >> @PostConstruct

  3. 需要注意的是,注解会影响到服务器的启动速度。服务器在启动时候会遍历Web 应用的WEB-INF/classes下的所有class文件与WEB-INF/lib下的所有jar文件,以检查哪些类使用了注解。如果应用程序中没有 使用任何注解,可以在Web.xml中设置的metadata-complete属性为true

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/119766.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!