Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@ConfigurationProperties requires class to be mutable in Kotlin #4563

Closed
jasperblues opened this issue Nov 20, 2015 · 10 comments
Closed

@ConfigurationProperties requires class to be mutable in Kotlin #4563

jasperblues opened this issue Nov 20, 2015 · 10 comments

Comments

@jasperblues
Copy link

Is it possible to get @ConfiguraitonProperties to inject a matching constructor? Otherwise in Kotlin it is necessary to declare the configured properties as public and mutable, which is not ideal.

Also, in Kotlin, the @value annotation is a little ugly, since "${something}" is a language feature and must be escaped.

I generally love using Spring Boot and Kotlin together - what could be more fun? But things get a little ugly when it comes to external configuration.

@snicoll
Copy link
Member

snicoll commented Nov 20, 2015

What's Kotlin specific exactly? @ConfigurationProperties requires a regular "POJO" with public properties. Isn't that the exact same thing? What do you mean by a matching constructor?

@snicoll snicoll added the status: waiting-for-feedback We need additional information before we can continue label Nov 20, 2015
@jasperblues
Copy link
Author

It is my understanding that in Java we can make the @ConfigurationProperties object immutable, by:

  • Having private fields
  • Including public getters

. . and that the object will be configured using reflection. In Kotlin, this didn't work. The properties had to be mutable. (I'll attach a sample in a moment).

What do you mean by a matching constructor?

  • I mean that rather that set fields by reflection, look for a constructor whose parameter names match required properties and inject that. Ah, but I recall now that in Java/JVM languages constructors don't provide parameter-name reflection, right? So only type-signature matching would be possible, with isn't very practical in the case of a configuration holder (likely lots of strings, etc).

@snicoll
Copy link
Member

snicoll commented Nov 20, 2015

It is my understanding that in Java we can make the @ConfigurationProperties object immutable

No. As I said, in Java you need a regular JavaBean property (public getter/setter). We don't support anything else at the moment and your request is not kotlin specific either (unless I am mistaken).

Duplicates #1254

@snicoll snicoll closed this as completed Nov 20, 2015
@jasperblues
Copy link
Author

Ah, I see! I assumed config objects would naturally lean towards being immutable.

👍 on 1254 for myself as well then :)

Thank you.

@sdeleuze
Copy link
Contributor

@jasperblues Do you have any Kotlin @Value usage example to share?

@jasperblues
Copy link
Author

Sure:

@Component
class TokenAuthenticationProvider : AuthenticationProvider
{
    val profileRepo : ProfileRepository
    val apiKey : String

    //---------------------------------------------------------------------------------------
    //MARK: - Constructors
    //---------------------------------------------------------------------------------------

    @Autowired constructor(profileRepo: ProfileRepository, @Value("\${service.api.apiKey}") apiKey: String)
    {
        this.profileRepo = profileRepo
        this.apiKey = apiKey
    }


    //etc . . . 

Unfortunately as "${something}" is a language feature in Kotlin, it needs to be escaped. I asked on Stackoverflow for a quick/easy way to customize the property placeholder prefix and suffix in Spring Boot - waiting for advice.

@sdeleuze
Copy link
Contributor

@jasperblues Could you try with #{something} instead of ${something}?

@jasperblues
Copy link
Author

@sdeleuze Out of the box, with standard Spring Boot, that does not work. However, I suspect if you changed the PropertyPlaceholderConfigurer with to one that had appropriate prefix and suffix it would.

@sdeleuze
Copy link
Contributor

@jasperblues In fact, using # is probably not good idea since this prefix is already used for evaluating SpEL expressions, but it is indeed possible to customize the prefix used by declaring a PropertySourcesPlaceholderConfigurer (not PropertyPlaceholderConfigurer) in your configuration.

More details on my answer on Stackoverflow.

@jasperblues
Copy link
Author

@sdeleuze Thank you, sir :)

@philwebb philwebb removed the status: waiting-for-feedback We need additional information before we can continue label Dec 2, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants