简体   繁体   中英

Spring MethodInvokingBean - The value returned is not accepted by DriverManagerDataSource

I have tried looking on google about the problem, but not able to get a solution.

What I am trying to achieve

See the below code, what I am trying to do is pass an encrypted password to MethodInvokingBean , which uses com.xxxxxxx.CryptoUtil to decrypt is using a static method decrypt .

The decrypted value is injected into masterDBDatasource via <property name="password" ref="decryptedDBPassword" /> , but it is not working.

<bean id="decryptedDBPassword" class="org.springframework.beans.factory.config.MethodInvokingBean">
       <property name="targetClass" value="com.xxxxxxx.CryptoUtil"/>
       <property name="targetMethod" value="decrypt"/>
       <property name="arguments" value="${encrypted.db.password}" />
    </bean>

    <bean id="masterDBDatasource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${db.driver.class}" />
        <property name="url" value="${db.url}" />
        <property name="username" value="${db.username}" />
        <property name="password" ref="decryptedDBPassword" />
    </bean>

Exception

org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'org.springframework.beans.factory.config.MethodInvokingBean' to required type 'java.lang.String' for property 'password'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.beans.factory.config.MethodInvokingBean] to required type [java.lang.String] for property 'password': no matching editors or conversion strategy found

I followed the below tutorial as a reference

https://www.mkyong.com/spring/spring-methodinvokingfactorybean-example/

I also tried <property name="password" value="decryptedDBPassword" /> But the DB connection is saying - access denied due to invalid password.

Kindly help.

Posting exact answer for my problem code as a reference for other people, who might be facing similar problem.

From @Matt's Hint, I have final config as below using SPeL (without using MethodInvokingBean )

<bean id="masterDBDatasource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${db.driver.class}" />
        <property name="url" value="${db.url}" />
        <property name="username" value="${db.username}" />
        <property name="password" value='#{T(com.xxxxxxx.CryptoUtil).decrypt("${encrypted.db.password}")}' /> 
</bean>

The property password should be a String value. You are passing a bean ( decryptedPassword ) reference to the DriverManagerDataSource that expects a String as a password. It should be like

<property name="password" value="${db.password} />

similar to the username you provide.

As you need to pass the decrypted password you might want to take a look at Spring's expression support, that would let you process the password before passing it.

http://docs.spring.io/spring/docs/3.0.0.M3/spring-framework-reference/html/ch07s04.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM