java 加载spring_java与Spring中的资源加载

private String resolveName(String name) {

if (name == null) {

return name;

}

if (!name.startsWith("/")) {

Class c = this;

while (c.isArray()) {

c = c.getComponentType();

}

String baseName = c.getName();

int index = baseName.lastIndexOf('.');

if (index != -1) {

name = baseName.substring(0, index).replace('.', '/')

+"/"+name;

}

} else {

name = name.substring(1);

}

return name;

}

这就说明了

1最终都是通过ClassLoad进行加载的

2第二种方式是可以使用相对路径的,也就是资源相对于本类路径下的路径

如果本来的包名为com.xx.test 下面有一个xx.xml文件和xx.java类。

我们在xx.java类中想加载xx.xml。那么它的路径可以写为:

/com/xx/xx.xml 或者是 xx.cml。

同样的道理如果test包下面还有一个text包,这个包里面有一个yy.java

那么相对路径就是../xx.xml就可以加载到资源。

如果是ClassLoad.getResource(str);这种方式只能写路径的全限定名,不加“/”,也就是com/xx/xx.xml

后又测试了几种文件xml properties 和包路径是可以的 但是java类却不行后追踪源码发现

private ClassLoader parent;

public URL getResource(String name) {

URL url;

if (parent != null) {

url = parent.getResource(name);

} else {

url = getBootstrapResource(name);

}

if (url == null) {

url = findResource(name); // return null

}

return url;

}

这里我们可以看到加载顺序是会始终找到它的父类或者祖先类直到没有了父类为止

然后到Bootstrap(基本类装入器是不能有java代码实例化的,由JVM控制)加载。

部分源码:

private static URL getBootstrapResource(String name) {

try {

// If this is a known JRE resource, ensure that its bundle is

// downloaded. If it isn't known, we just ignore the download

// failure and check to see if we can find the resource anyway

// (which is possible if the boot class path has been modified).

sun.jkernel.DownloadManager.getBootClassPathEntryForResource(name);

} catch (NoClassDefFoundError e) {

// This happens while Java itself is being compiled; DownloadManager

// isn't accessible when this code is first invoked. It isn't an

// issue, as if we can't find DownloadManager, we can safely assume

// that additional code is not available for download.

}

URLClassPath ucp = getBootstrapClassPath();

Resource res = ucp.getResource(name);

return res != null ? res.getURL() : null;

}

测试代码:

测试类结构图:

com.xx.MyTest

- com.xx.text.MyTestC

appconfig.xml

appconfig.properties

public class MyTest {

@Test

public void testResource() throws IOException {

URL url3 = this.getClass().getResource("appconfig.xml");

//or URL url3 = this.getClass().getResource("/com/xx/MyTest/appconfig.xml");

URL url4 = this.getClass().getClassLoader().getResource("com/xx/MyTest/appconfig.properties");

System.out.println(url4.getFile());

System.out.println(url3.getFile());

}

public URL printResourceCs(String str) throws IOException {

URL url3 = this.getClass().getResource(str);

System.out.println(url3.getFile());

return url3;

}

public URL printResourceCL(String str) throws IOException {

URL url3 = this.getClass().getClassLoader().getResource(str);

System.out.println(url3.getFile());

return url3;

}

}

为了测试继承关系得到的基础url:

public class MyTestC extends MyTest {

@Test

public void testA() throws IOException {

Assert.assertNotNull(printResourceCs("../appConfig.xml"));

Assert.assertNotNull(printResourceCL("sl/ewfs/dms/action/appConfig.xml"));

}

}

应用:

1 当我们需要加载xml,或者properties 配置文件时,有时候需要这样做。

2 利用ClassLoad我们可以得到项目运行是的根目录getClassLoader().getResource("")即可

附上加载properties 代码:

public void loadPropertiesFromXML(String XMLPath) throws IOException { URL url = getClass().getResource(XMLPath);

InputStream is = null;

URLConnection con = null;

Properties p = new Properties();

try {

con = url.openConnection();

p.loadFromXML(is = con.getInputStream()); //p.load(is = con.getInputStream()); } catch (IOException e) {

throw e;

} finally {

if (is != null) {

try {

is.close();

} catch (IOException e) {

e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

}

}

}

}

再来看看Spring的资源加载:

Spring的Resource接口代表底层外部资源,提供了对底层外部资源的一致性访问接口。

对应层次图

b3bbd5e2015f4cc86d2f79231e383a6d.png

uml:

dcc8685c79249460bd8c6fe9232312c2.png

其中,最常用的有四个:

ClassPathResource:通过 ClassPathResource 以类路径的方式进行访问;

FileSystemResource:通过 FileSystemResource 以文件系统绝对路径的方式进行访问;

ServletContextResource:通过 ServletContextResource 以相对于Web应用根目录的方式进行访问;

UrlResource :通过java.net.URL来访问资源,当然它也支持File格式,如“file:”。

当然你也可以通过ApplicationContext 来取得Resource

这会带来少许的方便,因为当你可以实现ApplicationContextAware来方便的得到ApplicationContext

然后使用

applicationContext.getResource("commons/lib/xx/xx.xx").getFile().getAbsolutePath();

就可以得到资源的绝对路径

下段是applicationContext getResource 的代码

String CLASSPATH_URL_PREFIX = “classPath”;

public Resource getResource(String location) {

Assert.notNull(location, "Location must not be null");

if (location.startsWith(CLASSPATH_URL_PREFIX)) {

return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());

}

else {

try {

// Try to parse the location as a URL...

URL url = new URL(location);

return new UrlResource(url);

}

catch (MalformedURLException ex) {

// No URL -> resolve as resource path.

return getResourceByPath(location);

}

}

}

Resource参考:

http://wade6.iteye.com/blog/1706941

http://jinnianshilongnian.iteye.com/blog/1416319

http://jinnianshilongnian.iteye.com/blog/1416320

http://jinnianshilongnian.iteye.com/blog/1416321

http://jinnianshilongnian.iteye.com/blog/1416322

java 类加载机制:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/

2cc4e371cf4d4d380f0ee597e48ae210.png

大小: 176.7 KB

44f597de0b28dfea14fc749ebd758930.png

大小: 746 KB

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2013-04-26 16:58

浏览 4013

评论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值