无法在Kotlin中创建Spring Data Event Listener

时间:2015-10-29 16:16:46

标签: java spring spring-data kotlin spring-data-neo4j-4

我尝试创建一个这样的事件监听器:

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

。 。 。但它不会编译。在指定泛型类型的情况下,编译器返回:

Type argument expected

我做错了什么?

2 个答案:

答案 0 :(得分:2)

问题是您可以使用几个可能的BeforeSaveEvent类。以下是一些模拟出来的Spring类,以向您展示差异(注意两个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的角度来看,它可以帮助您提出相关课程的声明签名(点击进入找到你正在使用的课程,它可能不是你认为的那个。)

答案 1 :(得分:1)

不确定您想要实现的目标,但一个简单的解决方法是在返回语句中添加object关键字:

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

object表示您返回该类的对象,而不是代码中的sttrange事物。我还添加了override,因为我怀疑onApplicationEventApplicationListener的方法,所以必须覆盖它。

实际上,如果您只有一个这样的对象,那么您可以直接使用object作为单身人士:

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