热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Spring自动注入失败的解决方法

这篇文章主要介绍了Spring自动注入失败的解决方法,帮助大家更好的理解和学习使用Spring框架,感兴趣的朋友可以了解下

Spring自动注入失败如何解决?

我有一个被Spring @Service注解的类(MileageFeeCalculator),它有一个用@Autowired注入的变量(rateService),但是当我用这个变量的时候,它显示为null。日志显示MileageFeeCalculator bean和MileageRateService bean都被创建了,但是当我调用service上的mileageCharge ()方法时,就会报NullPointerException错误。为什么Spring不能自动注入这个实例?

Controller:

@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = new MileageFeeCalculator();
        return calc.mileageCharge(miles);
    }
}

Service:

@Service
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService; // <--- should be autowired, is null

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile()); // <--- throws NPE
    }
}

本应被注入Service但是并没有的类

@Service
public class MileageRateService {
    public float ratePerMile() {
        return 0.565f;
    }
}

为什么我调用GET /mileage/3这个请求的时候,会报这样的错误:

java.lang.NullPointerException: null
    at com.chrylis.example.spring_autowired_npe.MileageFeeCalculator.mileageCharge(MileageFeeCalculator.java:13)
    at com.chrylis.example.spring_autowired_npe.MileageFeeController.mileageFee(MileageFeeController.java:14)
    ...

回答

@Autowired注解的字段为null是因为,Spring无法获取你用new关键字创建的类,也无法自动注入它。

Spring Ioc容器有三个主要的逻辑组件:应用程序可以使用的注册表(ApplicationContext);通过把依赖项与上下文中的bean匹配,将依赖的对象注入的配置器系统;以及一个依赖解析器,它可以查看许多不同bean的配置,并确定如何按必要的顺序实例化和配置它们。

Ioc容器并没有魔法,除非你以某种方式通知它,否则它无法获取Java对象。当你调用new创建对象时,JVM实例化新对象,并将其中一个副本交给你——它并不经历Spring的配置过程。有三种方法可以配置bean实例。

注入你的bean

最好的选择是让Spring注入所有的bean;这样的代码量会最少并且也最容易维护。为了使注入如你所愿,需要把MileageFeeCalculator像这样注入。

@Controller
public class MileageFeeController {

    @Autowired
    private MileageFeeCalculator calc;

    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        return calc.mileageCharge(miles);
    }
}

如果你需要为不同的请求都创建一个类的新实例,可以通过Spring注解的scopes实现。

使用@Configurable

如果你真的需要把new出来的对象保存进行注入,那可以使用Spring的@Configurable注解,通过使用AOP在编译时织入你的对象中。这种方法将代码插入到对象的构造函数中,提醒Spring这个对象正在被创建,这样Spring就能够配置新实例了。这需要你添加一些配置信息。并打开Spring的运行时配置处理器。Roo Active Record系统使用这种方法来允许实体的new实例获取注入的必要持久性信息。

@Service
@Configurable
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService;

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile());
    }
}

手动查找bean:不推荐

这种方法只适用于在特殊情况下与遗留代码对接。创建一个Spring可以自动注入并且遗留代码也能调用的单例适配器总是可取的,但是也许可以直接向spring application context请求bean实例。

为了做到这点,你需要一个类,该类提供了对ApplicationContext对象的引用

@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        cOntext= applicationContext;   
    }

    public static ApplicationContext getContext() {
        return context;
    }
}

之后你的遗留代码就可以调用getContext()方法获取所需的bean实例了。

@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = ApplicationContextHolder.getContext().getBean(MileageFeeCalculator.class);
        return calc.mileageCharge(miles);
    }
}

以上就是Spring自动注入失败的解决方法的详细内容,更多关于Spring自动注入失败的解决的资料请关注其它相关文章!


推荐阅读
  • 前言Git是目前最流行的版本控制系统,在它的基础之上,GitHub和GitLab成为当前最流行的代码托管平台,它们均提供的代码评审、项目管理、持续集成等功能,越来越多的互联网企业都 ... [详细]
  • Eclipse 下 JavaFX 程序开发指南
    本文介绍了 JavaFX,这是一个用于创建富客户端应用程序的 Java 图形和媒体工具包,并详细说明了如何在 Eclipse 环境中配置和开发 JavaFX 应用。 ... [详细]
  • 精通C++并非易事,为何它比其他语言更难掌握?这主要归因于C++的设计理念,即不强迫用户接受特定的编程风格或限制创新思维。本文探讨了如何有效学习C++,并介绍了几本权威的学习资源。 ... [详细]
  • 本文探讨了STL迭代器的最佳实践,包括iterator与const_iterator、reverse_iterator及其const版本之间的关系,以及如何高效地转换和使用这些迭代器类型。 ... [详细]
  • 使用Jenkins构建Java项目实践指南
    本指南详细介绍了如何使用Jenkins构建Java项目,包括环境搭建、工具配置以及项目构建的具体步骤。 ... [详细]
  • 本文将详细介绍Docker的网络架构,包括Docker自带的几种网络模式及其创建方法,探讨容器间及容器与外部世界的通信方式。此外,还将简要介绍单主机环境下的容器网络配置。 ... [详细]
  • 本文旨在介绍在iOS平台进行直播技术开发前的准备工作,重点讲解AVFoundation框架的基本概念和使用方法。通过对AVFoundation的深入理解,开发者能够更好地掌握直播应用中的音视频处理技巧。 ... [详细]
  • Waymo大规模采购FCA车型,软银巨资加码Cruise,无人驾驶商业化步伐加快
    近期,无人驾驶领域迎来两项重大进展:软银以22.5亿美元投资通用汽车旗下的Cruise Automation,同时Waymo宣布向菲亚特克莱斯勒采购62000辆厢式车。这些动向不仅提升了行业信心,也为无人驾驶技术的商业化铺平了道路。 ... [详细]
  • Python多线程编程详解
    本文深入探讨了Python中的多线程机制,包括线程的基本概念、创建线程的方法以及线程间的通信策略。 ... [详细]
  • 本文介绍了如何通过自定义配置类,利用 `WebMvcConfigurer` 接口来扩展 Spring MVC 的功能,实现默认首页的自动跳转,同时避免使用 `@EnableWebMvc` 注解全面接管 Spring MVC 的默认配置。 ... [详细]
  • 当在Windows环境下使用Docker运行容器时,如果忘记了添加-d参数,容器将以交互模式启动。本文将指导您如何安全地退出这种模式而不终止Docker容器。 ... [详细]
  • Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据
    go,通过,map,filter,foreach,等,流,式,ap ... [详细]
  • 前端常用的布局类型——前端布局
    1.Static静态布局固定宽高:2.Liquid流式布局宽高用百分比,按屏幕分辨率调整,布局不发生变化3.Adaptive自适应 ... [详细]
  • 本文详细介绍了如何在Spring Boot项目中配置Maven的pom.xml文件,包括项目的基本信息、依赖管理及构建插件的设置。 ... [详细]
  • CSS Grid布局属性详解及媒体查询应用
    本文详细介绍了CSS Grid布局的各种属性,并探讨了如何利用Grid布局实现媒体查询功能,以适应不同设备的显示需求。 ... [详细]
author-avatar
手机用户2502904457
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有