Spring 注入(inject)工具 :map in Kotlin with type safety

标签 spring dependency-injection kotlin autowired

我在 XML 中有几个 bean 定义来在外部存储我的 SQL。我想将它们注入(inject) Kotlin 为 Map<String,String>但是,到目前为止,我能够使其工作的唯一方法是将其注入(inject)为 Map<Any,Any> .有没有办法在这里确保类型安全。将其注入(inject)为 Map<Any,Any>感觉贫民窟。

当我尝试 Map<String,String>甚至Map<String,Any>我没有找到合格的 bean ......

示例 XML

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util.xsd
                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <util:map id="brandSql" key-type="java.lang.String" value-type="java.lang.String">
        <entry key="selectBrands">
            <value type="java.lang.String">
                <![CDATA[
                SELECT
                    ID,
                    NAME
                FROM BRAND
                ]]>
            </value>
        </entry>
    </util:map>

</beans>

注入(inject)服务
@Service
open class JdbcBrandService @Autowired constructor(
    private val namedJdbcTemplate: NamedParameterJdbcTemplate
): BrandService {

    companion object {
        val logger = LoggerFactory.getLogger(JdbcBrandService::class.java)
    }

    @Autowired
    @Qualifier(value = "brandSql")
    private lateinit var queries: Map<Any,Any>

    /// methods and what not go here
}

在 Java 中,我可以做以下类似的事情,但 Kotlin 的类型系统更严格似乎可以防止这种情况发生。
@RestController
public class JavaBrandController {

    private final Map<String, String> brandSql;

    @Autowired
    public JavaBrandController(@Qualifier("brandSql") Map sql) {
        this.brandSql = sql;
    }

    @GetMapping("/javaBrands")
    public Map getBrandSql() {
        return this.brandSql;
    }
}

最佳答案

就个人而言,让像 Map<String, String> 这样的泛型类型的 bean 漂浮在周围感觉很奇怪。 .当您需要其他 map 时,它会造成困惑。

我要做的是创建一个容器类来保存对 map 的引用,这样你就有了一个合适的类型来引用。

例子:

class SqlConfig(val map: Map<String, String>)

然后在你的 xml 中创建一个这种类型的 bean:
<util:map id="brandSql" key-type="java.lang.String" value-type="java.lang.String">
    <entry key="selectBrands">
        <value type="java.lang.String">
            <![CDATA[
            SELECT
                ID,
                NAME
            FROM BRAND
            ]]>
        </value>
    </entry>
</util:map>

<bean id = "sqlConfig" class = "test.package.SqlConfig">
   <constructor-arg ref = "brandSql"/>
</bean>

现在,您可以根据需要使用正确的类型以非 Guetto 方式 Autowiring 它:
@Autowired
@Qualifier(value = "sqlConfig") // <-- the qualifier is no longer needed
private lateinit var queries: SqlConfig

关于 Spring 注入(inject)工具 :map in Kotlin with type safety,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47355423/

相关文章:

hibernate - 在创建 spring、hibernate with maven 时在 pom.xml 中添加依赖项时发现多个注释出现错误

c# - 将属性注入(inject) QuartzJobObject

android - 字符串未正确初始化?

Spring引导2.1.2, hibernate 5 : Register Hibernate Event Listeners (Insert/Update/Delete)

mysql - Hibernate 和 MySql 的 Hikaricp : one of either dataSource or dataSourceClassName must be specified

java - 在这种情况下,如何使 spring 在使用泛型时注入(inject)正确的 bean?

c# - Autofac 作为 AWS Lambda Serverless ASP.NET Core 3.1 Web API 中的 IoC 容器

javascript - 编译为 Javascript 时使用 Java Standard Library for Kotlin

java - Kotlin 委托(delegate)给 future

java - Spring boot RestTemplate 发布 400 错误