Injecting a classpath resource into a Spring 3 bean - java

There is a property of type Resource in my Spring 3 bean that should be injected with a reference to a file in the classpath. I use the #Value annotation as below to hopefully achieve this.
public class TestBean
{
#Value("classpath:/abc/student/test.sql")
private Resource SqlFile;
...
}
But the property is always null. I have confirmed that the sql file has been deployed in the maven target directory (it is at target/classes/abc/student/test.sql).
The closest solutions that I could google were this and this which detail the xml way whereas I am interested in doing this using annotations.
Appreciate any pointers on what could be wrong here.
Thanks,
Vijay

If it's going to be hard-coded like that, then just
private Resource sqlFile = new ClassPathResource("/abc/student/test.sql");
Otherwise, what you're really after is
#Value("${some.property}")
private Resource sqlFile;
and I believe that in injecting the property value, the correct PropertyEditor will be applied.

If you don't want to specify a property then this should work
#Value("${:classpath:json/inventory.json}")
Resource inventory;

Related

How to access value defined application.properties file outside of class in Spring Boot [duplicate]

Is it possible to define the value of a #RequestMapping annotation in Spring by defining it in a properties file?
Actually, I do something like:
#Controller
#RequestMapping("/xxx")
public class MyController {
...
}
But I would like to store the path /xxx in a properties file. Why? For instance, it is less likely that I do mystakes in my templates if I rename the path in the controller.
In other framework this is allowed (see Symfony, for instance).
It should be possible to use placeholders in #RequestMapping, like for example #RequestMapping("${foo.bar}"). Take a look at the documentation for more details:
Patterns in #RequestMapping annotations support ${…​} placeholders against local properties and/or system properties and environment variables. This may be useful in cases where the path a controller is mapped to may need to be customized through configuration. For more information on placeholders, see the javadocs of the PropertyPlaceholderConfigurer class.
Thx for the help. It is my contribution...
No dependencies are necessary because maven do everything by itself.
In the property file - use maven interpolation, such as below:
vs= v1
us= users
me= messages
url.user=${vs}/${us}
url.mess=${vs}/${me}
In your destiny file, for example controller/resource (in mycase):
#RestController
//#RequestMapping("v1/users") <<<<<<instead this
#RequestMapping("${url.user}")<<<<<<use this
#Api(value = "API RESTFUL)
public class UserResource {
//
As bohuslav burghardt has mentioned this is totally possible.
So if you have a common domain stored in your application.properties file you can use placeholders to call it in your controller/s and even chain placeholders & text together.
For Example...
In your .properties file
app.domain = mydomain/v1
In the controller
#RestController
#RequestMapping("${app.domain}/my-controller")
public class MyController {

How to name #Component from properties file?

I am using spring. I know how to use properties data inside a class but I need to know how to give component name from the properties file.
#Component("componentName") // here I need to give my property instead of "componentName".
public class TestClass {
}
I do search abt it but not able to find sos! Please help me...
I'm afraid that is not possible. All names that is given to #Controller, #Service and so on requires to be final/constant.
If you can use additional XML config, use alias directive as explained in this other question:
<beans>
<alias name="${service.class}" alias="Service"/>
<context:property-placeholder location="example/app.properties"/>
<context:component-scan base-package="example"/>
<beans>
If you need to use java config only, there's an open issue about it here. It is still unresolved, so for strictly java config the same is not currently possible.
If that's a problem, you can also register a bean programmatically as detailed here. So you'd autowire a property and your target bean, implement BeanDefinitionRegistryPostProcessor and register your bean in the registry you get as a parameter using your property.
I'm not sure if I understand correctly, from Spring 3 or up, you can use
#PropertySource annotation to externalize your configuration to a properties file. And then display the values with #Value
If you are talking about distinguishing configuration beans, #Qualifier is the thing you are looking for

Spring 4 conditional - Accessing a resource

Doing my first steps with spring 4 I tried the #Conditional annotation following this article.
My problem -
I would like to get access to a classpath resource (basically a properties file) from method matches in class OnSystemPropertyCondition.
To do that currently I'm loading the required properties file from the matches method every time it is invoked (which means for every class annotated with the ConditionalOnSystemProperty annotation).
This is a bit ugly. I thought that an elegant solution would be to simply autowire my resource or some properties (using the #Value annotation) but this can't be done since this class gets instanciated before the beans.
Any suggestions than can help me avoid reload this resource again and again?
The single method of the annotation gets in its signature the input param ConditionContext context. You can obtain an Environment from the context by calling context.getEnvironment(). The environment gives access to all my resources (look at this to see how to get access to your resources via spring environment).

Is Spring's #Value annotation part of internationalization?

I am working on a project where internationalized messages are retrieved using the #Value annotation.
e.g.:
#Value("${email.newUser.subject}")
private String NEW_USER_SUBJECT;
#Value("${email.newUser.message}")
private String NEW_USER_MESSAGE;
However, as part of my investigation, it appears that the #Value annotation is used to get a property from a property file and does not link into to automatic lookup of the correct version of the message.properties. Therefore as I understand it, this is only working by coincidence because we have currently only a single message.properties file.
Can anyone in the know tell me if I have the correct understanding of the situation?
The Answer is No, the #Value annotation is not part of Internationalization. It's use in conjunction with Internationalization is an error and will break when you try to change the Local.

How can I make properties in properties files mandatory in Spring?

I have an ApplicationContext.xml file with the following node:
<context:property-placeholder
location="classpath:hibernate.properties, classpath:pathConfiguration.properties" />
It specifies that both properties files will be used by my application.
Inside pathConfiguration.properties, some paths are defined, such as:
PATH_ERROR=/xxx/yyy/error
PATH_SUCCESS=/xxx/yyy/success
A PathConfiguration bean has setters for each path.
The problem is: when some of those mandatory paths are not defined, no error is thrown. How and where should I handle this problem?
The standard behaviour of the PropertyPlaceholder that is configured via <context:property-placeholder ... /> throws an exception when a property cannot be resolved once it is required in some place as long as you do not configure it otherwise.
For your case if you have a Bean that requires some properties like this, it will fail when the value cannot be resolved. For example like this:
public class PropertiesAwareBean {
#Value("${PATH_ERROR}")
private String errorPath;
String getErrorPath() {
return errorPath;
}
}
If you want to relax the PropertyPlaceholder and don't make it throw an Exception when a property cannot be resolved you can configure the PropertyPlaceholder to ignore unresolvable properties like this <context:property-placeholder ignore-unresolvable="true" ... />.
One way to reinforce the verification of parameters is to switch to a classical PropertyPlaceholderConfigurer bean in your beans file.
The PropertyPlaceholderConfigurer has properties which you can use to tweak its behavior and specify either an exception is thrown or not if some key is missing (take a look at setIgnoreUnresolvablePlaceholders or setIgnoreResourceNotFound).
If I remember correctly, in Spring 2.5, only the location attribute is supported for <context:property-placeholder> (things might have changed though).
I'm not sure if I fully understand your issue, but there are probably a variety of ways to approach this. One would be to make the paths mandatory by using constructor injection. In the constructor you could then validate the incoming values and if null for example, throw BeanInitializationException instances.

Categories

Resources