简体   繁体   中英

spring - GenericXmlApplicationContext loading from classpath

I'm newly at spring.

I can't understand why when I write some easy example and try it load with ApplicationContents as follows:

package com.appres.prospring3.ch5.factory;

public class MessageDigestExample {
    public static void main(String[] args) {
        GenericXmlApplicationContext context = new GenericXmlApplicationContext();
        context.load("classpath:factory/factory.xml");
        context.refresh();

        MessageDigester digester = (MessageDigester) context.getBean("digester");
        digester.digest("Hello World !!!!!!!!!");
    }
}

Exactly after this one line :

context.load("classpath:factory/factory.xml");

Going exception message:

17:59:44,480 INFO eans.factory.xml.XmlBeanDefinitionReader: 315 - Loading XML bean >definitions from class path resource [factory/factory.xml] Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: >IOException parsing XML document from class path resource [factory/factory.xml]; nested >exception is java.io.FileNotFoundException: class path resource [factory/factory.xml] >cannot be opened because it does not exist

To my mind all should work. And I couldn't figure out what is wrong here.

Here is my project structure:

包中的类路径

But when I move myFile.xml to resources package:

资源路径

And change context.load() to context.load("classpath:factory.xml");

All works fine and I can see correct result:

Using digest1
Using algorithm: SHA1
[B@5e9ed26e
Using digest2
Using algorithm: MD5
[B@d09644a

Edit:

Of course I tried longest paths for loading this .xml file, as:

context.load("classpath:com/appress/prospring3/ch5/factory/factory.xml");

And it throws bunch of exceptions :

Exception in thread "main" 18:15:22,385  INFO eans.factory.xml.XmlBeanDefinitionReader: 315 - Loading XML bean definitions from class path resource [com/appress/prospring3/ch5/factory/factory.xml]
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [com/appress/prospring3/ch5/factory/factory.xml]; nested exception is java.io.FileNotFoundException: class path resource [com/appress/prospring3/ch5/factory/factory.xml] cannot be opened because it does not exist
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
    at org.springframework.context.support.GenericXmlApplicationContext.load(GenericXmlApplicationContext.java:105)
    at com.appres.prospring3.ch5.factory.MessageDigestExample.main(MessageDigestExample.java:8)
Caused by: java.io.FileNotFoundException: class path resource [com/appress/prospring3/ch5/factory/factory.xml] cannot be opened because it does not exist
    at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:158)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328)
    ... 7 more

- Why exactly this happen?
- Does exist some way do this from the same location. Where is main()?

There are two problems with the first version.

  1. The xml file is placed under src/main/java and not under src/main/resources . When Maven build your project, it expects to find only Java source files under src/main/java , and ignores all the other files. Resource files must be placed under src/main/resources . That's the Maven convention.
  2. The code loads the file from the resource factory/factory.xml. This means that factory.xml should be in the package factory to be found. But the file is in the package com.appres.prospring3.ch5.factory .

The first version will work as well after adding the full package name to the path:

context.load("classpath:com/appress/prospring3/ch5/factory/factory.xml");

It's still better to leave the config file in the resources folder, because config files by convention should always go there.

The classpath: prefix is always relative to the root of your classpath. Therefore

context.load("classpath:factory/factory.xml");

is looking for factory.xml at /factory/factory.xml at the root of the classpath, which you obviously don't have. You need to put the fully qualified package name to find it where it is

context.load("classpath:com/appress/prospring3/ch5/factory/factory.xml");

The src/main/resources folder is a Maven convention. Maven will take all files in that folder and add them to the root of the classpath (or relative to their nested folders/packages. Therefore in your 2nd example, factory.xml finds its way to the root of the classpath and you can access it with

context.load("classpath:factory.xml");

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