Is it possible to insert a value stored in a configuration file (eg: application.properties) inside java annotation as follows :
#MyAnnotation(name="${application.prop1}")
and in application.properties I have:
application.prop1=foo
So that at runtime I have :
#MyAnnotation(name="foo")
Yeah, I don't think this is possible. Spring has no idea about your annotation and doesn't know what to do with it. Even if you try to use #Value(..) on top of your String name() default "" (inside of your annotation), Spring still won't make this happen as the annotation is not a bean. Trying to make your annotation a bean won't work either as far as I can tell. It sound like you are going to have to come up with some type of processor for this.
Perhaps looking into the following topics might help give you some ideas on how to put this together:
Auto Configuration: https://www.baeldung.com/spring-boot-custom-auto-configuration
SPeL: https://www.baeldung.com/spring-expression-language
Java Reflection: http://tutorials.jenkov.com/java-reflection/index.html
And of course, there's always the possibility that you might want to step back and consider why you want to do this? What are you trying to achieve that perhaps can be done a more "out of the box" way.
Yes, yse #Value annotation
#Value("property1")
Related
I am trying to achieve something like below. This might be stupid question but I wanted to know if that's possible or any other ways of to do it.
-- src
--test
--pkg1
--Pkg1_class1
--Pkg1_class2
--pkg2
--Pkg2_class1
--Pkg2_class2
--tests
--testPkg1
--Pkg1_TestClass1
--testPkg2
--Pkg2_TestClass1
I have used #Component annotation for all the classes that need to be injected, and it works fine.
But I have a requirement that when I run the tests from testPkg1, I want spring DI to create only the beans required for those objects i.e. only for the classes in pkg1 above. And, the sameway, when I run the tests from testPkg2, I don't want to create beans for the classes inside pkg1 as I don't need them or no intention to use at all for these tests.
I understand that we are telling the spring to scan for the packages that need to be injected. Wondering is there a way we can filter that based on some condition on annotations or something like that.
Please feel free to correct me if my understanding is wrong or the question. Appreciate it.
As #Giorgi Tsiklauri mentioned in comment, you can use profiles or you can use
EnableAutoConfiguration's exclude property:
..
#EnableAutoConfiguration(exclude={Class1ofPkg2.class,Class2ofPkg2.class ,..})
public class YourTestClassofPkg1{
Using the #Value annotation, is there any way to check (other than if-statements) if spring failed to do the injection and defaulted to null? Say, for example, you're doing it for 10+ variables; it would be rather extensive to go through the chain of if-statements. My intention is to track which failed, and throw an exception listing them. If possible, I'd rather not use reflection but I wouldn't mind if it was cleaner than a chain of if-statements.
UPDATE
Here's an example:
#Value("${my.package.username:#{null}}")
private String username;
When my.package.username isn't defined for Spring as my.package.username=someUserName in application.properties or as a JVM argument for Tomcat to pick it up in the form of
-Dmy.package.username=someUserName then it should default to null, which it does. Now, imagine there are 10+ of the above declaration for different variables, I would like to know how to determine which are null without checking each one. I was thinking there may be functionality in Spring to determine which failed since spring is doing the injection.
Spring treats "environment" as a normal property source, so it will not care too much from which property source came the final value.
In the example you gave you use null as fallback value, so you do a little opposite to what you would like to achieve.
But there are i think some tricks:
1) try to set some spring classes logging to DEBUG or even TRACE, maybe in logs it will be possible to find the information you want
2) if you want to know that within the program, then you really need to have distinction between the file property source and other, and do few ifs...
Let say I want to check condition[let say boundary values] on some of the method arguments.Instead of writing "if" condition to check [boundary condition] on every method, I want to annotate argument only. Let me know the Steps to understand it. Working code will be awesome.
You need to look into method interception. What you are wanting is an interceptor that can validate method arguments on invocation. I like the AOP Alliance interfaces for this, they work pretty well. It also integrates with Guice natively and I think Spring has support for it as well.
Steps:
Define an annotation
Create an interceptor to process the annotation
Bind the interceptor (manually or using some framework)
I was working on validation using annotation in Struts2 and i was quite surprised to see that the annotations does not have a LongRangeFieldValidator where as the validations done using xml does have a LongRangeFieldValidator
I tried different ways to get the LongRangeFieldValidor using annotations.
LongRangeFieldValidator. It showed an error because it doesn't actually exists and com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator cannot be converted to an Annotation type. This was quite obvious so i switched to next.
I used IntRangeFieldValidator. I could quite use it because it was unable to do a typecasting. I thought this should have worked because docs says it is for numeric types.
DoubleRangeFieldValidator This one also validates (and it should) non-integer values so i had to drop this.
Finally I had to convert my long field to a String and had to use RegexFieldValidator.
My question is why there isn't a LongRangeFieldValidator in the package com.opensymphony.xwork2.validator.annotations and what are the best practices to obtain it?
It seems they forgot to add this annotation to the core package. Just a mistake may be or so, but there is the workaround. Use a custom validator annotation
#CustomValidator(type ="long", fieldName = "myField")
under registered validators you can find the name of the validator long.
I was reading the Jersey docs about bean validation. The ParameterNameProvider example shows how to define parameter names for a method. However, the implementation looks like this will have to be done for each and every method which obviously doesn't scale. The example is basically useless as is.
Is there a smarter way to do this? Couldn't Jersey infer the name from #QueryParam or #PathParam annotations?
Take a look at the answer in my question here. It should do exactly what you want.
Can I change the property path in a ConstraintValidator for Method arguments?
If you copy my code and run it through a debugger you will see that it is only evaluated once for each method for which it is used. Then during normal running of your app the names will not need to be resolved again.