简体   繁体   中英

Spring classpath resource overwritten

I have a class which uses the following code:

@Value(value = "classpath:mail_template.html")
private Resource template;

According to this tutorial this would allow me to get data from a file inside my jar file using template.getInputStream() . This worked correctly until another mail_template.html was added in another module.

My application has a main_application who's POM has the other modules as dependencies. The structure is as follows:

main_application
    |
    - modulue_1 (another module)
        |
        - src/main/java
        - src/main/resources
            |
            - mail_template.html
    - modulue_2 (my module)
        |
        - src/main/java
        - src/main/resources
            |
            - mail_template.html

So now my class uses module_1's mail_template.html instead of the one I have inside my module. As I understand this is the correct behavior since module_1 is loaded first and @Value gets injected with the first mail_template.html that it finds, but this would not be correct in my case since it overrides the resource in module_2 (and subsequent modules as well) that has the same name in module_1.

Is it possible to specify to use the current class (or module) to find a resource in the src/main/resources directory in the @Value annotation? Or must I uniquely name every resource in every module to avoid this problem?

I have tried many different "classpath:" routes including:

@Value(value = "classpath:module_2/mail_template.html")
....
@Value(value = "classpath*:mail_template.html")
...
@Value(value = "classpath*:module_2/mail_template.html")

But all of these result in a FileNotFoundException .

EDIT

Each module is composed as follows:

Maven POM Project
    Maven Java Application
        src/main/java
            base.package.with.module.name.as.suffix.package
        src/main/resources
            resource_files_if_needed

As stated, each module is declared as a dependency under the Maven Java Application main_application and each Maven Java Application uses a "base package" with the module's name as a suffix.

For example:

// main_application:
    package my.main.application
// module_1:
    package my.main.application.module1
// module_2:
    package my.main.application.module2

This is used so Spring can load the classes with @Component annotations using <context:component-scan base-package="my.main.application" /> in the config file.

You can only have one mail_template.html in the classpath. This is also true for classes with the same package and class name.

I would suggest to us a different directory name in the resource directory.

I beleive, it actually skips classpath in the @Value expression. I think the problem is : after classpath . The : in the @Value refers the separator character to separate property key and default value. For example, below code looks for key project.123.gender and if it is not available then returns Male as default.

@Value("${project.123.gender:Male}")

Could you try something like below? I have not tested it, but looks like that could be one possible issue. (note the extra : at start)

@Value(value = ":classpath:mail_template.html")

OR

@Value(value = "${:classpath:mail_template.html"})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM