-
Notifications
You must be signed in to change notification settings - Fork 38.4k
Consider not overriding meta-annotation attributes if empty [SPR-11709] #16331
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
Comments
Juergen Hoeller commented This is an interesting one, and I can definitely see your argument here. The question is basically how to design a custom optional argument that only overrides if it's actually set, with the original default value from the overridden annotation applying otherwise. However, there are also cases where you may want to explicitly override with an empty value, resetting an original default value through an override with "" or an empty array... We could theoretically differentiate between an explicitly specified empty value and a defaulted empty value in the annotation declaration, but that's not very clean - neither conceptually nor implementation-wise - and should therefore be a last resort only. This might be a case where an explicit attribute-level annotation would help, clearly indicating a specific attribute's override intention. I have been asked before whether we would support such an annotation for general validation reasons, in a JDK Juergen |
Gary Russell commented Thanks; it would be great if we can come up with a scheme to conditionally determine whether an empty value should override that on the meta-annotation. |
Sam Brannen commented Hi guys, The (note: when I say "never", I obviously mean for the status quo) Without some new mechanism in place, the best practice is to:
This best practice can be seen in Spring Boot's @SpringApplicationConfiguration. Specifically, in Now... I can understand that the copy-n-paste approach is perhaps not very desirable for annotations that have several attributes, but it is currently the only way to achieve your goal. Note as well that redeclared attributes in composed annotations can optionally change the defaults of the target meta-annotation while still allowing for attribute overriding. Regards, Sam |
Sam Brannen commented In other words, I would consider your configuration broken, and this is how you fix your annotation:
Regards, Sam |
Sam Brannen commented
Just to be clear... this is not specific to ASM-based annotation processing. The same is true for reflection-based processing with |
Sam Brannen commented
I hope that my explanation above explains how to achieve this. Of course, with the status quo, getting the "original default value from the overridden annotation applying otherwise" requires that one manually copy all such declarations from the overridden annotation. It works, but it's not ideal. However, as you suggested, introducing "an explicit attribute-level annotation" might be an elegant solution. - Sam |
Gary Russell commented Thanks, Sam; that makes sense; and I can see how we can achieve the desired behavior this way. BTW, one thing I noticed while researching this is that I presume this is intentional but it makes it difficult to handle and I had to roll my own code to recurse up the chain; I'd be interested in your (and Juergen Hoeller's) comments as to whether this (proposed) implementation is naive... Note that it stops after it finds the first reference to the required annotation and does not deal with the case that the target annotation might exist multiple times in the hierarchy. This is fine for SI as we'll just document the limitation. Any suggestions for improvements are appreciated. Thanks. |
Sam Brannen commented
Please note that Excerpt from the class-level Javadoc for
Thus if you are currently invoking Please let us know if this helps. Thanks, Sam |
Sam Brannen commented
It's only partially intentional. We actually already have support for this in Instead of forcing you to roll your own code, we could consider introducing an overloaded Thoughts? Sam |
Sam Brannen commented Gary Russell, if the information provided in my previous comments does not help you solve your issue regarding your custom algorithm for finding an annotation on a method (potentially as a nested meta-annotation), would you please open a separate JIRA issue to address that topic? Thanks, Sam |
Gary Russell commented Hi Sam Brannen, I am traveling at the moment; I'll take a look tonight or tomorrow, unless Artem Bilan beats me to it. Gary |
Artem Bilan commented Hi, Sam! Thank you, your help is appreciated. @interface A {
String foo();
}
@A(foo = "bar")
@interface B {
String foo() default "";
}
@B
@interface C {
}
What is good here the expression Take a look, please, to the polishing for our PR: spring-projects/spring-integration#1132. Hope Gary will add some comments on the matter. However I don't see now so much issues to disturb you. |
Gary Russell commented Thanks, Sam, I think we have a way forward with your suggested use of overrides in your first and second comments. For now, we are just not going to allow override to If Spring Framework 4.1 (or later) provides some mechanism to support that, we can move to it at that time. We'll just use our local work-around until then rather than trying to synch. up with a 4.0.x SF version. Thanks again Gary |
Sam Brannen commented Just to reiterate, the following is not the proper way to declare @A(foo = "bar")
@interface B {
String foo() default "";
} Instead, you have to declare @A
@interface B {
String foo() default "bar";
} |
Sam Brannen commented
That was true when this issue was first raised; however, this problem has been fixed in #17534. Regards, Sam |
Sam Brannen commented Gary Russell & Artem Bilan, you might be interested in knowing that For details, please read my comments in SPR-12738. Pay special attention to the new
Regards, Sam p.s. there is currently no equivalent of |
Sam Brannen commented I'm resolving this issue as "Works as Designed". See previous comments detailing best practices for supporting annotation attribute overrides with required vs. default semantics. If someone feels that Spring needs an "explicit attribute-level annotation ... that clearly indicates a specific attribute's override intention" (as suggested by Juergen Hoeller), feel free to open a separate JIRA issue. Regards, Sam |
Artem Bilan commented Sam Brannen, thank you very much for such a comprehensive support and explanations! Indeed, we must be consistent and follow with standard rules on the matter. We'll take a look to our engine what should be changed in line of Spring Framework behavior. |
Gary Russell opened SPR-11709 and commented
In
AnnotationReadingVisitorUtils.getMergedAnnotationAttributes()
, the attributes closer to the annotated element override those in the hierarchy.It would be useful if this only occurred if the closer attribute was not-empty.
For example:
This allows the user to override the "default" setting in the meta-annotation, but the current logic replaces the default with "" if the user does not specify a value when using the annotation.
The same applies to attributes with array values; consider preventing the override of a higher-up array with an empty array closer to the declaration.
Affects: 4.0.3
Issue Links:
0 votes, 5 watchers
The text was updated successfully, but these errors were encountered: