Невозможно создать прослушиватель событий Spring Data в Котлине

Я попытался создать прослушиватель событий следующим образом:

@Bean open fun beforeSaveEventApplicationListener(): ApplicationListener<BeforeSaveEvent> { return ApplicationListener<BeforeSaveEvent>() { fun onApplicationEvent(event: BeforeSaveEvent) { //Do something with event } } } 

, , , но он не будет компилироваться. Если указан общий тип, компилятор возвращает:

 Type argument expected 

Что я делаю не так?

    Проблема в том, что существует несколько возможных классов BeforeSaveEvent которые вы могли бы использовать. Вот некоторые из весенних классов, издевавшихся, чтобы показать вам разницу ( обратите внимание на две объявления BeforeSaveEvent ):

     open class ApplicationEvent(source: Any): EventObject(source) {} interface ApplicationListener<T: ApplicationEvent> { fun onApplicationEvent(event: T) } // the Spring Data Neo4j version requires a type class BeforeSaveEvent<T>(source: Any, val entity: T): ApplicationEvent(source) {} // the Spring data version does not class BeforeSaveEvent(source: Any): ApplicationEvent(source) {} 

    И поэтому, если вы скопируете версию Spring, ваш код будет следующим:

     open class Something { open fun beforeSaveEventApplicationListener(): ApplicationListener<BeforeSaveEvent> { return object : ApplicationListener<BeforeSaveEvent> { override fun onApplicationEvent(event: BeforeSaveEvent) { //Do something with event } } } } 

    Если вы укажете версию Neo4j (я думаю, что вы, потому что ваши теги для вашего вопроса включают spring-data-neo4j-4 ), вы также должны указать параметр типа сущности:

     class MyEntity {} open class Something { open fun beforeSaveEventApplicationListener(): ApplicationListener<BeforeSaveEvent<MyEntity>> { return object : ApplicationListener<BeforeSaveEvent<MyEntity>> { override fun onApplicationEvent(event: BeforeSaveEvent<MyEntity>) { //Do something with event } } } } 

    Итак, вы точно видите, что запрашивал компилятор:

    Пожалуйста, дайте мне параметр типа для BeforeSaveEvent потому что это действительно BeforeSaveEvent<T>

    Возможно, вы импортировали неправильный класс и означали другой BeforeSaveEvent или вы импортировали правильный BeforeSaveEvent<T> и не адаптировались к его фактическим потребностям типового типа.

    Кроме того, поскольку ApplicationListener – это интерфейс, который вы не хотите () после его использования, потому что это означает, что вы пытаетесь вызвать конструктор интерфейса.

    ПРИМЕЧАНИЕ. Это помогает в ваших вопросах предоставить подписывание объявлений относительных классов, с точки зрения IDE (попросите его щелкнуть, чтобы найти класс, который вы используете, возможно, это не тот, который вы считаете собой).

    Не уверен, чего вы хотели достичь, но простым решением было бы добавить ключевое слово object в оператор return:

     @Bean open fun beforeSaveEventApplicationListener(): ApplicationListener<BeforeSaveEvent> { return object : ApplicationListener<BeforeSaveEvent>() { override fun onApplicationEvent(event: BeforeSaveEvent) { //Do something with event } } } 

    object означает, что вы возвращаете объект этого класса, а не объект sttrange, который был в вашем коде. Также я добавил override так как я подозреваю, что onApplicationEvent – это метод ApplicationListener , поэтому он должен быть переопределен.

    На самом деле, если с вами нормально иметь только один такой объект, вы можете использовать object в качестве одноэлементного:

     @Bean object beforeSaveEventApplicationListener: ApplicationListener<BeforeSaveEvent>() { override fun onApplicationEvent(event: BeforeSaveEvent) { //Do something with event } }