本文介绍了我可以编写使用自动装配的Spring bean的Kotlin扩展功能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个扩展函数,其实现使用Spring bean.似乎不可能通过在软件包的顶层定义扩展功能来做到这一点.我试过了:

I'm trying to create an extension function whose implementation uses a Spring bean. It didn't seem possible to do this by defining the extension function at the top level of a package. I tried this:

@Component
class Converter {

    companion object {
        @Autowired
        lateinit var transformer: Transformer

        fun Class1.convert(): Class2 {
            return Class2 (this, transformer.transform(someStringProperty))
        }
    }
}

其中,transform是将某些字符串转换为另一字符串的函数,而Class1是具有someStringProperty属性的某些类.我希望其他类可以import pkg.Converter.Companion.convert,然后可以使用x.convert(),其中x是类型为Class1的对象.

where transform is a function that transforms some string to another string, and Class1 is some class that has a someStringProperty property. My hope was that other classes could import pkg.Converter.Companion.convert and then be able to use x.convert() where x is an object of type Class1.

语法有效,在其他类中使用x.convert()可以正常编译.但这会在运行时导致异常:kotlin.UninitializedPropertyAccessException: lateinit property transformer has not been initialized

The syntax works, and using x.convert() in other classes compiles fine. But it results in an exception at run time: kotlin.UninitializedPropertyAccessException: lateinit property transformer has not been initialized

看起来Spring没有自动装配变量,因为它在同伴对象中,而不是实际的组件对象中.

It looks like Spring isn't autowiring the variable because it's in a companion object and not an actual component object.

@Component注释伴随对象无效.

我不认为直接在Converter内部移动Class1.convert是可行的,因为使用x.convert()需要一个Converter对象的实例,并且我不知道如何使用扩展名来执行此操作.函数语法.

I don't think moving Class1.convert directly inside Converter would work, because then using x.convert() would need an instance of the Converter object, and I don't see how to do this with the extension function syntax.

有什么办法可以做到这一点,还是我必须放弃扩展函数的语法?

Is there any way to accomplish this, or do I have to give up on the extension function syntax?

推荐答案

扩展功能可以使用文件范围私有变量,并且可以在组件的@PostConstruct方法,将"this"分配给私有变量.这种设计将组件的依赖关系添加到扩展功能中,现在它们都绑定到同一个私有变量.但是,如果两者都存在相同的问题,我认为这是可以容忍的,而且似乎没有其他更好的方法.

The extension function can use the file scope private variable and in thecomponent's @PostConstruct method, assign "this" to the private variable.This design adds a dependency from component to the extension function,now they are both binding to the same private variable. But if they both are in the same problem, I think it is tolerable and there seems no other better way.

@Component
public class ClassOne {
    var value = Random.nextInt()

    @PostConstruct
    private fun init() {
        c1 = this
    }
}

private lateinit var c1 : ClassOne
fun String.appendC1() : String {
    return this + c1.value
}

及其测试代码:

@RunWith(SpringRunner::class)
@ContextConfiguration(classes = [ClassOne::class])
class DependencyInjectionTest {
    @Autowired
    lateinit var autowiredConfiguration : ClassOne

    @Test
    fun testAccessComponentInExtension() {
        Assert.assertEquals(autowiredConfiguration.value, c1.value)
    }
}

这篇关于我可以编写使用自动装配的Spring bean的Kotlin扩展功能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 00:29