如何在Springboot中调用方法
注意:这旨在作为常见问题的规范答案。
我有一个带有字段()的Spring
@Service
类(MileageFeeCalculator
),但是该字段是我尝试使用它时所用的。日志显示同时创建了bean和bean,但是每当尝试在服务bean上调用方法时,我都会得到一个。Spring为什么不自动接线该领域?@Autowired``rateService``null``MileageFeeCalculator``MileageRateService``NullPointerException``mileageCharge
控制器类:
@Controllerpublic class MileageFeeController {
@RequestMapping("/mileage/{miles}")
@ResponseBody
public float mileageFee(@PathVariable int miles) {
MileageFeeCalculator calc = new MileageFeeCalculator();
return calc.mileageCharge(miles);
}
}
服务等级:
@Servicepublic class MileageFeeCalculator {
@Autowired
private MileageRateService rateService; // <--- should be autowired, is null
public float mileageCharge(final int miles) {
return (miles * rateService.ratePerMile()); // <--- throws NPE
}
}
应该自动连接的服务bean,MileageFeeCalculator
但不是:
@Servicepublic 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不知道MileageFeeCalculator
您使用其创建的副本,new
也不知道自动对其进行接线。
Spring Inversion of
Control(IoC)容器具有三个主要的逻辑组件:ApplicationContext
应用程序可以使用的组件(bean)的注册表(称为),配置器系统通过匹配对象将对象的依赖项注入到它们中在上下文中具有bean的依赖关系,以及一个依赖关系解决程序,它可以查看许多不同bean的配置并确定如何以必要的顺序实例化和配置它们。
IoC容器不是魔术,除非您以某种方式告知Java对象,否则它无法了解Java对象。当您调用时new
,JVM实例化新对象的副本并将其直接交给您-
它从未经历配置过程。您可以通过三种方式配置bean。
我已经在GitHub项目上使用Spring
Boot启动了所有这些代码;您可以针对每种方法查看一个正在运行的项目,以查看使其工作所需的一切。
回答:
最可取的选择是让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使用注入。
回答:
如果确实需要new
自动创建的对象,则可以将Spring
@Configurable
注释与AspectJ编译时编织一起使用以注入对象。这种方法将代码插入到对象的构造函数中,以警告Spring正在创建它,以便Spring可以配置新实例。这需要在构建中进行一些配置(例如使用进行编译ajc
)并打开Spring的运行时配置处理程序(@EnableSpringConfigured
使用JavaConfig语法)。Roo
Active Record系统使用此方法来允许new
您的实体实例获取注入的必要持久性信息。
@Service@Configurable
public class MileageFeeCalculator {
@Autowired
private MileageRateService rateService;
public float mileageCharge(final int miles) {
return (miles * rateService.ratePerMile());
}
}
回答:
这种方法仅适用于在特殊情况下与遗留代码接口。几乎总是最好创建一个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);
}
}
以上是 如何在Springboot中调用方法 的全部内容, 来源链接: utcz.com/qa/423838.html