Чтобы вызвать прослушиватели событий, Spring должен знать класс слушателя и поместить его в applicationContext
, что называется Bean .
. Вам нужно аннотировать ваш класс с @Component
. Но когда вы делаете это, вы получаете ошибку. Давайте проясним это.
Краткий обзор Spring
Наличие класса, помеченного @Component
, будет указывать Spring на то, что ему нужно "управлять" самим классом. Управляя, он включает в себя создание всех «зависимостей», а затем вызов «конструктора». Давайте назовем это деревом зависимостей . Как только Spring достигнет дна, он может начать подниматься и создавать объект и возвращаться к вершине.
Управление зависимостями
Spring знает зависимости вашего класса, анализируя конструктор , сеттер или атрибуты, помеченные @Autowired
. Обратите внимание, что если в вашем классе есть только один конструктор, Spring автоматически сканирует его, чтобы узнать о зависимостях, даже если в его верхней части нет @Autowired
.
В вашем случае для CustomSpringEventListener
у вас есть один конструктор, принимающий параметр String. Если мы построим дерево зависимостей вашего CustomSpringEventListener
, мы получим что-то вроде этого:
CustomSpringEventListener ---> String
Так что, когда Spring попытается создать ваш CustomSpringEventListener
, он будет искать бин типа String
, потому что ваш код говорит: если вы когда-нибудь захотите создать объект CustomSpringEventListener
, вам нужно дать имя, которое является строкой. Но в вашем коде нет бина типа String, я думаю.
Решение
Сначала аннотируйте свой класс CustomSpringEventListener
с помощью @Component
и удалите свой атрибут и конструктор.
@Component
public class CustomSpringEventListener implements ApplicationListener<CustomSpringEvent> {
@Override
@EventListener
public void onApplicationEvent(CustomSpringEvent event) {
System.out.println("Received spring custom event - " + event.getMessage());
}
}
Во второй раз найдите другой способ иметь имя в вашем классе, если оно вам действительно нужно.
Слушатель с атрибутами
Давайте скажем, вам нужен более сложный слушатель, например, использующий ServiceA
. Вы можете сделать следующее:
@Service
public class ServiceA { ... }
@Component
public class CustomSpringEventListener implements ApplicationListener<CustomSpringEvent> {
private ServiceA serviceA;
public CustomSpringEventListener(ServiceA serviceA) {
this.serviceA = serviceA;
}
}
Тот же слушатель с именем
Вы можете объединить класс @Configuration
, чтобы создать много раз одного и того же слушателя. Давайте используем ваш первый Listener с атрибутом name
.
public class CustomSpringEventListener implements ApplicationListener<CustomSpringEvent> {
private String name;
public CustomSpringEventListener(String name) {
this.name = name;
}
@Override
@EventListener
public void onApplicationEvent(CustomSpringEvent event) {
System.out.println(name + " received spring custom event - " + event.getMessage());
}
}
Без аннотации @Component
вы можете использовать класс @Configuration
для создания экземпляра Listener:
@Configuration
public ListenerConfig {
public CustomSpringEventListener listenerA() {
return new CustomSpringEventListener("listenerA");
}
public CustomSpringEventListener listenerB() {
return new CustomSpringEventListener("listenerB");
}
public CustomSpringEventListener listenerC() {
return new CustomSpringEventListener("listenerC");
}
...
}
Вы можете смешивать конфигурацию Spring с любой необходимой конфигурацией.
Надеюсь, это поможет.