projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.86k stars 2.38k forks source link

[FEATURE] Support annotations on generated constructor when the annotation is not allowed on a field #2531

Open mtwig opened 4 years ago

mtwig commented 4 years ago

This could be viewed as either an improvement, or a new feature.

Lombok does not support default values on constructors using annotations. Spring already supports this. Lombok can almost be used to use the Spring default constructor values to a constructor. The "problem" is that Lombok only supports copying an annotation which is allowed on a field. The Spring @DefaultValue annotation is annotated to only be allowed on a parameter. The current Lombok behaviour of copying the annotation to the getter, setter, and constructor doesn't quite work, as the annotation is not allowed on fields or methods.

Desired Lombok code:

@Data
@RequiredArgsConstructor
public class SampleConfiguration {

    private final String valueWithoutDefault;

    @DefaultValue("DefaultValue")
    private final String valueWithDefault;

}

This currently produces a compiler warning: DefaultValue' not applicable to field

lombok.config:

lombok.copyableAnnotations = org.springframework.boot.context.properties.bind.DefaultValue
lombok.anyconstructor.addConstructorProperties=true

Java code currently required:

@Data
public class SampleConfiguration {

    private final String valueWithoutDefault;
    private final String valueWithDefault;

    @ConstructorProperties({"valueWithoutDefault", "valueWithDefault"})
    public SampleConfiguration(String valueWithoutDefault, @DefaultValue("DefaultValue") String valueWithDefault){
        this.valueWithoutDefault = valueWithoutDefault;
        this.valueWithDefault = valueWithDefault;
    }

}

I'm using Lombok with a SpringBoot ConfigurationProperties configuration class. When properties do not have default values, the combination is extremely nice. As soon as you need to support a default value (cannot assume that the application config has a default value set for the default spring profile) you're basically forced to start maintaining your own constructor, or overwriting specific getters. It would be real nice if Lombok could support moving some annotations, rather than copying. I suspect to keep the functionality generic, using a configuration similar to lombok.copyableAnnotations would be a good approach.

Rawi01 commented 4 years ago

In general the compiler is right about that one, there actually is an annotation at the wrong place. Unfortunately we can do nothing to fix this because javac refuses to call lombok in this case. What might be possible is to wrap the annotation in a different annotation with an invalid parameter. That way lombok gets called and the annotation can be copied to the right place. Example:

@AllArgsConstructor
class A {
    @Copy(@DefaultValue)
    private String a;
}

As an alternative it might be possible to use meta annotations or something similar for this one. But all that is a lot of work...

Disclaimer: I'm not a project owner.