Java Spring注入存储库与构造函数中的普通属性混合
我有Java Spring注入存储库与构造函数中的普通属性混合,java,spring,spring-boot,spring-data-jpa,Java,Spring,Spring Boot,Spring Data Jpa,我有Service类和Repository接口(Spring数据)。我还有一个抽象类: public abstract class TestingMethod { public TestingMethod() { timeSum = 0; } protected long timeSum; } 以及扩展它的类: @Component public class LimitTestingMethod extends TestingMethod {
Service
类和Repository
接口(Spring数据)。我还有一个抽象类:
public abstract class TestingMethod {
public TestingMethod() {
timeSum = 0;
}
protected long timeSum;
}
以及扩展它的类:
@Component
public class LimitTestingMethod extends TestingMethod {
@Autowired
private GeoTestDataRepository geoTestDataRepository;
private final int limitSize;
public LimitTestingMethod(int limitSize) {
super();
this.limitSize = limitSize;
}
}
在我的服务中
我想创建LimitTestingMethod
的实例,并设置其参数limitSize
。
比如:
LimitTestingMethod ltm3 = new LimitTestingMethod(3);
LimitTestingMethod ltm10 = new LimitTestingMethod(10);
但我有一个错误:
Description:中构造函数的参数0
com.exence.postgiscma.testingMethod.LimitTestingMethod需要一个bean
找不到类型为“int”的。行动:考虑定义一个
配置中的“int”类型的bean
这有可能实现我想要的东西吗
一切都好
//编辑
正如我在评论中看到的,这是一种糟糕的方法。所以也许有人会给我一些建议,如何更好地规划这个项目?
在构造函数中将repo作为参数传递是一个很好的解决方案吗(我想不是,但我不知道如何做得更好)
有好的、优雅的解决方案吗?当您在Spring范围之外创建实例时,您当前的解决方案将无法工作。这个错误是因为您用
@Component
对它进行了注释,它会在启动时检测到它,并尝试创建一个bean,但失败了
要解决这个问题,你可以做两件事中的一件
ApplicationContext
作为工厂来处理bean的创建,提供额外的参数,使bean原型具有范围ApplicationContext
手动创建实例之后,让Spring处理注入ApplicationContext
用作工厂
首先让你的bean成为一个原型,以便在需要时构建它
@组件
@范围(
可配置BeanFactory.SCOPE(原型)
公共类LimitTestingMethod扩展了TestingMethod{…}
现在,在启动期间不会创建实例。在您的服务中注入ApplicationContext
,并使用getBean
方法获取所需的实例
公共类服务{
@自动连线
私有应用上下文ctx;
公共方法(){
LimitTestingMethod ltm3=ctx.getBean(LimitTestingMethod.class,3);
LimitTestingMethod ltm10=ctx.getBean(LimitTestingMethod.class,10);
}
}
这将允许Spring使用传递给构造函数的值创建实例,并进行自动连接
创建后注入
另一个解决方案是手动创建实例,然后让Spring处理自动布线。你将失去AOP能力,只能自动布线
首先从LimitTestingMethod
中删除@组件
注释,以便在启动过程中不会检测到它
公共类LimitTestingMethod扩展了TestingMethod{…}
现在,在您的服务中,自动连接ApplicationContext
,并在创建bean之后使用它来注入依赖项
公共类服务{
@自动连线
私有应用上下文ctx;
公共方法(){
极限测试方法ltm3=新极限测试方法(3);
LimitTestingMethod ltm10=新的LimitTestingMethod(10);
ctx.getAutowireCapableBeanFactory().autowireBean(lmt3);
getAutowireCapableBeanFactory().autowireBean(lmt10);
}
}
两者都可以实现您想要的,但是,现在您的代码直接依赖于SpringAPI。因此,与此相反,您最好使用另一个选项,即通过构造函数注入LimitTestingMethod
的所有内容,然后自己传递存储库
使用构造函数创建实例
公共类LimitTestingMethod扩展了TestingMethod{
专用最终GeoTestDataRepository GeoTestDataRepository;
私人有限公司;
public LimitTestingMethod(int limitSize,GeoTestDataRepository GeoTestDataRepository){
这个。limitSize=limitSize;
this.geoTestDataRepository=geoTestDataRepository;
}
}
然后,您可以简单地自动连接服务类中的存储库,并根据需要创建实例(或者创建一个包含创建此对象的复杂性的工厂)
公共类服务{
@自动连线
私有数据存储库回购;
公共方法(){
LimitTestingMethod ltm3=新的LimitTestingMethod(3,回购);
LimitTestingMethod ltm10=新的LimitTestingMethod(10,回购);
}
}
当您在Spring范围之外创建实例时,您当前的解决方案将无法工作。这个错误是因为您用@Component
对它进行了注释,它会在启动时检测到它,并尝试创建一个bean,但失败了
要解决这个问题,你可以做两件事中的一件
ApplicationContext
作为工厂来处理bean的创建,提供额外的参数,使bean原型具有范围ApplicationContext
手动创建实例之后,让Spring处理注入ApplicationContext
用作工厂
首先让你的bean成为一个原型,以便在需要时构建它
@组件
@范围(
可配置BeanFactory.SCOPE(原型)
公共类LimitTestingMethod扩展了TestingMethod{…}
现在,在启动期间不会创建实例。在您的服务中注入ApplicationContext
,并使用getBean
方法获取所需的实例
公共类服务{
@自动连线
私有应用上下文ctx;
公共方法(){
LimitTestingMethod ltm3=ctx.getBean(LimitTestingMethod.class,3);
LimitTestingMethod ltm10=ctx.getBean(LimitTestingMethod.class,10);
}
}
这将允许Spring使用传递给构造函数的值创建实例,并执行au
LimitTestingMethod ltm3 = new LimitTestingMethod(3, geoTestDataRepository);