【Spring】Spring使用外部properties文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cflys/article/details/71107199

Spring使用外部properties文件



配置一个DataSource

当我们想要配置一个数据源的时候,首先导入c3p0和连接数据库(这里以mysql为例)所需要的jar包。
这里写图片描述

然后添加为库:
列表内容

接着编写我们的配置文件:
这里写图片描述

写个测试类进行测试:
这里写图片描述

运行一下,结果出错了,抛出了java.lang.ClassNotFoundException: com.mchange.v2.ser.Indirector

五月 03, 2017 4:19:22 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2b71fc7e: startup date [Wed May 03 16:19:22 CST 2017]; root of context hierarchy
五月 03, 2017 4:19:22 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [cn/wjinlong/spring/properties/beans-properties.xml]
五月 03, 2017 4:19:22 下午 org.springframework.context.support.ClassPathXmlApplicationContext refresh
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [cn/wjinlong/spring/properties/beans-properties.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mchange.v2.c3p0.ComboPooledDataSource]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [cn/wjinlong/spring/properties/beans-properties.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mchange.v2.c3p0.ComboPooledDataSource]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at cn.wjinlong.spring.properties.Main.main(Main.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mchange.v2.c3p0.ComboPooledDataSource]: No default constructor found; nested exception is java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147)
    ... 18 more
Caused by: java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
    at java.lang.Class.getConstructor0(Class.java:3075)
    at java.lang.Class.getDeclaredConstructor(Class.java:2178)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
    ... 19 more
Caused by: java.lang.ClassNotFoundException: com.mchange.v2.ser.Indirector
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 24 more

Process finished with exit code 1

不慌不慌,按道理说这个是c3p0包中的东西啊,这个包我们已经导入到project中了,不应该找不到类啊,先去百度一下。在github中c3p0的Issues中看到了同样的问题Class not found: com.mchange.v2.ser.Indirector #917,阅读后发现自己少导入了一个mchange-commons-java-0.2.11.jar,把mchange-commons-java-0.2.11.jar引入到项目中,添加为库。
这里写图片描述

继续测试:
这里写图片描述
没有问题测试成功了,但是有3行WARN什么鬼,不能忍啊,仔细读一遍发现是高版本的mysql建议我们使用ssl连接,在url中指定useSSL=true即可。
这里写图片描述
没毛病,不过好像偏离了重点。主要是出了个异常,接下来就进入重点。

使用properties文件

就像数据源的那些user、password这些配置信息直接写在Spring的配置文件中,总是有点不合适,比方说你换了一个数据库还需要去修改Spring的配置文件,就像我刚刚加一个useSSL=true也是去修改了Spring的配置文件,这样做是不太合适的,所以我们可以引入外部的properties文件,把类似user、password等配置信息写到一个db.properties中,然后再Spring中引用就好,这样子你以后修改数据库等操作只要修改db.properties就好,而不用去修改Spring的配合文件。

首先我们创建一个db.properties,把user、password等信息写在里面:
这里写图片描述

之后需要在Spring配置文件中引用db.properties,这时候需要引入一个org.springframework.beans.factory.config.PropertyPlaceholderConfigurer类来加载我们的properties文件。其中的location属性是用来指定properties文件的路径。然后使用${user}进行值的引用就好,运行了一下,没有问题。
这里写图片描述

在Spring2.5之后还可以引入context命名空间中的<context:property-placeholder> 进行配置。类似下图这样,截自官方文档。
这里写图片描述

我们引入context命名空间,然后然后像上图一样进行配置,然后运行,发现又抛出了异常。
这里写图片描述

通配符的匹配很全面, 但无法找到元素 ‘context:property-placeholder’ 的声明。
这个错误有点好笑啊,哈哈哈。不慌不慌这个之前在Bean的配置这篇文章中就遇到过,应该就是缺少了个xsd文件的引入。去官方文档里找,然后添加运行,成功运行。
这里写图片描述

总结

虽然过程中遇到了些小问题,但是解决问题的过程还是很令人享受的,总之就想说明一点:使用外部的properties文件可以简化Spring的配置文件,使其他系统比如说数据库的配置与Bean的配置分离,以便今后的维护。

没有更多推荐了,返回首页