为什么我的Spring @Autowired字段为空?

为什么我的Spring @Autowired字段为空?,第1张

为什么我的Spring @Autowired字段为空?

带注释的字段

@Autowired
null
因为Spring不了解
MileageFeeCalculator
你使用其创建的副本,
new
也不知道自动对其进行接线。

Spring Inversion of Control(IoC)容器具有三个主要的逻辑组件:

ApplicationContext
应用程序可以使用的组件(bean)的注册表(称为),配置器系统通过匹配对象将对象的依赖项注入到它们中在上下文中具有bean的依赖关系,以及一个依赖关系解决程序,它可以查看许多不同bean的配置并确定如何以必要的顺序实例化和配置它们。

IoC容器不是魔术,除非你以某种方式告知Java对象,否则它无法了解Java对象。当你调用时

new
,JVM实例化新对象的副本并将其直接交给你-它从未经历配置过程。你可以通过三种方式配置bean。

我已经在GitHub项目上使用Spring Boot启动了所有这些代码;你可以针对每种方法查看一个正在运行的项目,以查看使其工作所需的一切。用标记NullPointerException:nonworking

Inject your beans

最可取的选择是让Spring自动连接所有bean。这需要最少的代码量,并且最易于维护。要使自动装配工作如你所愿,还可以

MileageFeeCalculator
像这样自动装配:

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

如果你需要为不同的请求创建服务对象的新实例,仍然可以通过Spring bean scopes使用注入。

通过注入

@MileageFeeCalculator
服务对象起作用的标记:
working-inject-bean

Use@Configurable

如果确实需要

new
自动创建的对象,则可以将Spring @Configurable注释与AspectJ编译时编织一起使用以注入对象。这种方法将代码插入到对象的构造函数中,以警告Spring正在创建它,以便Spring可以配置新实例。这需要在构建中进行一些配置(例如使用进行编译
ajc
)并打开Spring的运行时配置处理程序(
@EnableSpringConfigured
使用JavaConfig语法)。Roo Active Record系统使用此方法来允许new你的实体实例获取注入的必要持久性信息。

@Service@Configurablepublic class MileageFeeCalculator {    @Autowired    private MileageRateService rateService;    public float mileageCharge(final int miles) {        return (miles * rateService.ratePerMile());    }}

通过@Configurable在服务对象上使用而起作用的标记:

working-configurable

Manual bean lookup: not recommended

这种方法仅适用于在特殊情况下与遗留代码接口。几乎总是最好创建一个Spring可以自动连接并且遗留代码可以调用的Singleton适配器类,但是可以直接向Spring应用程序上下文请求一个bean。

为此,你需要一个Spring可以引用该ApplicationContext对象的类:

@Componentpublic 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:

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

通过在Spring上下文中手动查找服务对象而起作用的标记:

working-manual-lookup



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4892882.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存