我有一个使用Spring Boot开发的maven项目。在活动类中定义注解@RequiredArgsConstructor形式Lombok时,有必要在应用程序启动时初始化@Service类Work的字段,该类扩展了Activity。我还需要在Work类的扩展字段中调用方法。活动和工作如下:
@RequiredArgsConstructor
public abstract class Activity<E extends Money> {
private final Calculator<E> calculator;
public Optional<E> findMoneyById(Long sumIdentification) {
return calculator.findById(sumIdentification);
}
}
@Service
public class Work extends Activity<Salary>{
private final SalaryCalculator salaryCalculator;
public Work(SalaryCalculator salaryCalculator) {
super(salaryCalculator);
this.salaryCalculator = salaryCalculator;
}
public List<Salary> getSalaries(Long amount){
return salaryCalculator.findAllByAmount(amount);
}
}
我试图在@Service子类的未初始化字段上调用该方法,但是我有一个NullPointerException。我还尝试了删除Activity类中的final修饰符,但是我遇到了编译问题,如果我尝试修改对超级构造函数的调用,以删除该调用中的参数,那么在测试类中,我又会出现NullPointerException异常。在调用超级构造函数之后初始化字段,我得到了预期的结果:测试通过,并且对该方法的调用起作用。我的问题是:在Java中调用super构造函数后,是否可以初始化字段?如果不是,或者不够优雅,是否有其他方法可以使我的所有代码在运行时进行编译,测试和应用程序运行?其他代码如下:
@Entity
public class Money{
@Id
@GeneratedValue
public Long id;
public Long getId() {
return id;
}
}
@Entity
@NoArgsConstructor
public class Salary extends Money{
private String currency;
private Long amount;
public Salary(Long amount) {
this.currency = "GBP";
this.amount = amount;
}
public String getCurrency() {
return currency;
}
public Long getAmount() {
return amount;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public void setAmount(Long amount) {
this.amount = amount;
}
}
public interface Calculator<T extends Money> extends JpaRepository<T, Long> {
Optional<T> findById(Long id);
}
public interface SalaryCalculator extends Calculator<Salary> {
List<Salary> findAllByAmount(long amount);
}
@ExtendWith(SpringExtension.class)
public class ActivityTest {
@MockBean
private Calculator<Salary> mockedCalculator;
@Test
void getSalary() {
Mockito.when(mockedCalculator.findById(Long.valueOf(1000))).thenReturn(Optional.of(new Salary()));
Activity<Salary> activity = new CalculatorImpl(mockedCalculator);
Optional<Salary> salary = activity.findMoneyById(Long.valueOf(1000));
assertNotNull(salary);
}
private class CalculatorImpl extends Activity<Salary>{
public CalculatorImpl(Calculator<Salary> calculator) {
super(calculator);
}
}
}
我要粘贴的代码是用于重现生产代码问题的简化应用程序,因此我只能进行修改,因此可以解决简化应用程序中的问题。