Java和Lombok-指定在调用@RequiredArgsConstructor定义的超级构造函数之后要初始化的字段

时间:2019-05-22 10:07:41

标签: java spring-data lombok

我有一个使用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);
        }

    }
}

我要粘贴的代码是用于重现生产代码问题的简化应用程序,因此我只能进行修改,因此可以解决简化应用程序中的问题。

0 个答案:

没有答案