Я пытаюсь написать класс уровня доступа, который получает данные от MongoDB с использованием Spring Data, но у меня есть следующая проблема: у меня есть следующий интерфейс:
public interface BlogDataRepository extends MongoRepository<Article, String> {
public Article findArticleByName(String name);
}
и класс уровня доступа:
@EnableAutoConfiguration
public class BlogDataAccessLayer {
@Autowired
private BlogDataRepository dataRepository;
...
}
И, наконец, основной класс:
@EnableAutoConfiguration
public class Test implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(Test.class, args);
}
public void run(String... args) throws Exception {
BlogDataAccessLayer layer = new BlogDataAccessLayer();
Article article = new Article("test", "first article");
layer.addArticle(article);
}
}
Каждый раз, когда я пытаюсь запустить приложение, я получаю NullPointerExeption
из dataRepository
находящегося в BlogDataAccessLayer
.
Я не понимаю, почему dataRepository
не автоуведомлен. Если я dataRepository
в Test
это dataRepository
.
Может кто-нибудь объяснить, почему я получаю такое поведение?
Я рассмотрю ваш код сверху вниз, первое, что нужно рассмотреть, это использование аннотации @Repository
на вашем уровне доступа к данным, в этом случае интерфейс BlogDataRepository
должен быть аннотирован этой аннотацией к стереотипу.
В смысле Domain Driven Design мы должны получить доступ к слою репозитория через сервисный уровень. поэтому в вашем случае BlogDataAccessLayer
действует как служебный уровень, и в этом случае @EnableAutoConfiguration
является избыточным, а в Spring echo системе @Service
уровня сервиса должны аннотироваться аннотацией @Service
.
Последняя и самая важная часть вашего кода, весенняя загрузка @EnableAutoConfiguration
не @EnableAutoConfiguration
beans в вашем пути к классу, и вы должны добавить @ComponentScan
в свой основной класс, в вашем случае Test
class.
обратите внимание, что в Spring Boot это хорошая практика для размещения вашего основного класса в корневом пакете и других классах в своем конкретном пакете. например, это хорошая практика:
org->Application.java //Test
org.service->FooService.java // BlogDataAccessLayer
org.repository->FooRepository // BlogDataRepository
если вы хотите использовать бобы в своих клиентских классах, вы должны их вводить. поэтому в вашем случае создание экземпляра BlogDataAccessLayer
с new
ключевым словом должно быть заменено на spring @Autowired
annotation. а также ваш Test
класс должен @Configuration
аннотацию @Configuration
.
Вам нужно автоустанавливать BlogDataAccessLayer
вместо создания экземпляра. Тогда только BlogDataRepository
внутри этого класса получает автообновление.