У меня есть веб-приложение Spring Boot, которое работает правильно.Я заметил, что два бина @Repository
имеют много общего, поэтому я реорганизовал их с помощью абстрактного суперкласса, и теперь мое приложение не работает.Я дважды проверил, и это единственное изменение, которое я сделал между рабочим и нерабочим состояниями.Кто-нибудь может увидеть, что я сделал не так?
Вот мой рабочий код:
public class One { ... }
public class Two { ... }
@Repository
public class RepoOne {
private final ISource<One> sourceOne;
private ICache<One> cache;
@Value("${com.example.lifetime.one}")
private int lifetime;
public RepoOne(ISource<One> sourceOne) {
this.sourceOne = sourceOne;
}
@PostConstruct
public void createCache() {
Duration lifetime = Duration.ofMinutes(this.lifetime);
this.cache = new Cache<>(lifetime, sourceOne);
}
public One get(String key) {
return cache.get(key);
}
}
@Repository
public class RepoTwo {
private final ISource<Two> sourceTwo;
private ICache<Two> cache;
@Value("${com.example.lifetime.two}")
private int lifetime;
public RepoOne(ISource<Two> sourceTwo) {
this.sourceTwo = sourceTwo;
}
@PostConstruct
public void createCache() {
Duration lifetime = Duration.ofMinutes(this.lifetime);
this.cache = new Cache<>(lifetime, sourceTwo);
}
public Two get(String key) {
return cache.get(key);
}
}
@Service
public class RepoService {
private final RepoOne repoOne;
private final RepoTwo repoTwo;
public RepoService(RepoOne repoOne, RepoTwo repoTwo) {
this.repoOne = repoOne;
this.repoTwo = repoTwo;
}
public void doSomething(String key) {
One one = repoOne.get(key);
...
}
}
Вот мой переработанный код, в котором я представил абстрактный обобщенный суперкласс.
abstract class AbstractRepo<T> {
private final ISource<T> source;
private ICache<T> cache;
AbstractRepo (ISource<T> source) {
this.source = source;
}
@PostConstruct
private void createCache() {
Duration lifetime = Duration.ofMinutes(lifetime());
this.cache = new Cache<>(lifetime, source);
}
protected abstract int lifetime();
public final T get(String key) {
return cache.get(key);
}
}
@Repository
public class RepoOne extends AbstractRepo<One> {
@Value("${com.example.lifetime.one}")
private int lifetime;
public RepoOne(ISource<One> sourceOne) {
super(source);
}
protected int lifetime() { return lifetime; }
}
@Repository
public class RepoTwo extends AbstractRepo<Two> {
@Value("${com.example.lifetime.two}")
private int lifetime;
public RepoTwo(ISource<Two> sourceTwo) {
super(source);
}
protected int lifetime() { return lifetime; }
}
При использовании переработанного кода я получаю NullPointerException
в AbstractRepo::get()
.Через отладчик я подтвердил, что cache
- это null
(вместе с source
).Однако я также подтвердил с помощью отладчика, что экземпляры RepoOne и RepoTwo созданы и вызван их метод createCache()
.Как будто создается два экземпляра каждого и инициализируется только один.Есть мысли?