Spring Injecting util:在Kotlin中使用类型安全的地图

时间:2017-11-17 16:41:11

标签: spring dependency-injection kotlin autowired

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

当我尝试Map<String,String>甚至Map<String,Any>时,我发现没有符合资格的豆类...

示例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>

注入服务

@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;
    }
}

1 个答案:

答案 0 :(得分:2)

就个人而言,让豆子浮动的感觉很奇怪,它们是Map<String, String>这样的通用类型。当你需要其他地图时会造成混乱。

我要做的是创建一个容器类,其中包含对地图的引用,因此您可以使用适当的类型进行引用。

示例:

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>

现在,您可以根据需要使用 non-guetto 方式中的正确类型自动装配它:

@Autowired
@Qualifier(value = "sqlConfig") // <-- the qualifier is no longer needed
private lateinit var queries: SqlConfig