Я пытаюсь создать приложение Swing с помощью Spring Boot. В корне моих пакетов у меня есть основной класс:
@SpringBootApplication
public class Application
{
public static void main(String[] args)
{
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
.headless(false)
.run(args);
System.out.println("Contains personRepository: " + ctx.containsBeanDefinition("personRepository"));
EventQueue.invokeLater(() ->
{
ApplicationFrame appFrame = ctx.getBean(ApplicationFrame.class);
appFrame.setVisible(true);
});
}
}
Насколько я понимаю, @SpringBootApplication должен найти любые компоненты Spring в пакетах под ним. Когда приложение запущено, оно запускает ApplicationFrame:
@Component
public class ApplicationFrame extends javax.swing.JFrame
{
@Autowired PersonRepository personRepository;
/**
* Creates new form ApplicationFrame
*/
public ApplicationFrame()
{
initComponents();
System.out.println("personRepository = " + personRepository);
}
}
PersonRepository находится в пакете под корнем и аннотируется @Repository.
@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {}
Когда я запускаю это, он возвращает:
Contains personRepository: true
personRepository = null
Таким образом, Application может найти репозиторий как bean-компонент, но ApplicationFrame не может его автоматически подключить. Я неправильно создаю ApplicationFrame или мне здесь чего-то не хватает?
Спасибо за любую помощь!
Похоже, это помогло. Спасибо! Можете ли вы сказать мне, почему, или указать мне на ресурс, который это объясняет?




Прежде всего, вам нужно удалить аннотацию @Repository из класса репозитория, поскольку это избыточная аннотация. Вместо этого вы должны аннотировать класс Application с помощью @EnableJpaRepositories - это более удобный способ работы с Spring Data.
О вашем выводе: вы видите personRepository = null в журнале, потому что этот оператор журнала находится внутри конструктора. На данный момент значение поля равно нулю.
В вашем случае вы используете внедрение поля - это означает, что Spring автоматически подключает bean-компоненты после создания объекта. Так что ничего плохого в классе ApplicationFrame, только с выходом.
Чтобы увидеть правильный результат, вы можете использовать инъекцию на основе конструктора:
@Component
public class ApplicationFrame extends javax.swing.JFrame
{
private final PersonRepository personRepository;
/**
* Creates new form ApplicationFrame
*/
public ApplicationFrame(final PersonRepository pr)
{
personRepository = pr;
initComponents();
System.out.println("personRepository = " + personRepository);
}
}
Хороший первый шаг - всегда заменять внедрение поля внедрением конструктора. Посмотрите, что произойдет, если вы это сделаете.