spring的DataSource数据源分析

在是使用spring时候,常常配置数据源,

 

<bean id="dataSource" 
	class ="org.springframework.jdbc.datasource.DriverManagerDataSoruce">

	<property name="driverClassName" value="org.apache.derby.jdbc.ClinetDriver">
	<property name="url" value="jdbc:derby://localhost:1527/news;create=true">
	<property name="username" value="admin">
	<property name="password" value="admin">
</bean>

 
在配置文件中共有四个需要注入的属性,在org.springframework.jdbc.datasource.DriverManagerDataSoruce这个类

中,共有5个属性

 

               private String driverClassName;

	private String url;

	private String username;

	private String password;

	private Properties connectionProperties;

 


其实用构造方法注入的方式也是可以的,因为spring除了生成setter方法外,也给我们提供了构造函数,

 

public DriverManagerDataSource(String driverClassName, String url, String username, String password)
			throws CannotGetJdbcConnectionException {
		setDriverClassName(driverClassName);
		setUrl(url);
		setUsername(username);
		setPassword(password);
}

 

 

其中的前四个是数据库连接的基本配置,而最后一个connectionProperties是通过配置文件properity读取数据库的连接配置,

看DriverManagerDataSoruce这个类是如何获取connection连接 就明白了

 

protected Connection getConnectionFromDriverManager(String url, Properties props)
	    throws SQLException {

		if (logger.isDebugEnabled()) {
			logger.debug("Creating new JDBC Connection to [" + url + "]");
		}
		return DriverManager.getConnection(url, props);
	}


	protected Connection getConnectionFromDriverManager(String username, String password)
	    throws SQLException {

		Properties props = new Properties(getConnectionProperties());
		if (username != null) {
			props.setProperty("user", username);
		}
		if (password != null) {
			props.setProperty("password", password);
		}
		return getConnectionFromDriverManager(getUrl(), props);
	}

 

其中DriverManagerDataSoruce这个类本身又继承至AbstractDataSource这个类,AbstractDataSource这个类继承至

javax.sql.DataSource类,在AbstractDataSource这个类中,什么也没做,只是一个简单的抽象类,并有几个简单的方

法,

 

public abstract class AbstractDataSource implements DataSource {

	protected final Log logger = LogFactory.getLog(getClass());

	/**
	 * Returns 0: means use default system timeout.
	 */
	public int getLoginTimeout() throws SQLException {
		return 0;
	}

	public void setLoginTimeout(int timeout) throws SQLException {
		throw new UnsupportedOperationException("setLoginTimeout");
	}

	/**
	 * LogWriter methods are unsupported.
	 */
	public PrintWriter getLogWriter() {
		throw new UnsupportedOperationException("getLogWriter");
	}

	/**
	 * LogWriter methods are unsupported.
	 */
	public void setLogWriter(PrintWriter pw) throws SQLException {
		throw new UnsupportedOperationException("setLogWriter");
	}

}

 返回来再看DriverManagerDataSource这个类,其实DriverManagerDataSource并不是一个有效的数据源实现,因为每

次被请求的时候都要为客户端打开一个新的连接。 spring提供了另一种实现是SingleConnectionDataSource,顾名思义,它只保留单一连接,总是重用该连接,永不关闭,这个显然不适合多线程环境。

 

public class SingleConnectionDataSource extends DriverManagerDataSource
  implements SmartDataSource, DisposableBean

SingleConnectionDataSource 本身又具有DriverManagerDataSource的所有属性,所以可以说

SingleConnectionDataSource 是DriverManagerDataSource的扩展和延伸,可以看到SingleConnectionDataSource 除

了继承DriverManagerDataSource外,本身又实现了俩个借口SmartDataSource和DisposableBean,下面先分别介绍这俩

个接口然后返回来介绍SingleConnectionDataSource 这个类.

SmartDataSource继承至javax.sql.DataSource这个接口,只是提供了一个方法
boolean shouldClose(Connection con);定义是否可以关闭连接。

DisposableBean接口也是定义了一个方法 void destroy() throws Exception;
方法的作用是在被调用BeanFactory时销毁一个连接,
返回看SingleConnectionDataSource类,先看这俩个接口是如何实现 。

 

/**
	 * This is a single Connection: Do not close it when returning to the "pool".
	 */
	public boolean shouldClose(Connection con) {
		synchronized (this.connectionMonitor) {
			return (con != this.connection && con != this.target);
		}
	}

 

看这个实现就明白,不用多说。在看另一个实现类

	public void destroy() {
		synchronized (this.connectionMonitor) {
			closeConnection();
		}
	}

 其中synchronized (this.connectionMonitor) 是同步的作用,防止死锁。
connectionMonitor的定义很简单

/** Synchronization monitor for the shared Connection */
private final Object connectionMonitor = new Object();

 

	/**
	 * Close the underlying shared Connection.
	 */
	private void closeConnection() {
		if (this.target != null) {
			try {
				this.target.close();
			}
			catch (Throwable ex) {
				logger.warn("Could not close shared JDBC Connection", ex);
			}
		}
	}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 前言 1. 简介 1.1. 概览 1.2. 使用场景 2. Spring 2.0 的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 更简单的XML配置 2.2.2. 新的bean作用域 2.2.3. 可扩展的XML编写 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.4. 中间层 2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. JPA 2.4.3. 异步的JMS 2.4.4. JDBC 2.5. Web层 2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. 动态语言支持 2.6.2. JMX 2.6.3. 任务规划 2.6.4. 对Java 5(Tiger)的支持 2.7. 移植到Spring 2.0 2.7.1. 一些变化 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. 控制反转容器 3.1. 简介 3.2. 容器和bean的基本原理 3.2.1. 容器 3.2.2. 实例化容器 3.2.3. 多种bean 3.2.4. 使用容器 3.3. 依赖 3.3.1. 注入依赖 3.3.2. 构造器参数的解析 3.3.3. bean属性及构造器参数详解 3.3.4. 使用depends-on 3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.7. 依赖检查 3.3.8. 方法注入 3.4. bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. 其他作用域 3.4.4. 自定义作用域 3.5. 定制bean特性 3.5.1. Lifecycle接口 3.5.2. 了解自己 3.6. bean定义的继承 3.7. 容器扩展点 3.7.1. 用BeanPostProcessor定制bean 3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. ApplicationContext 3.8.1. 利用MessageSource实现国际化 3.8.2. 事件 3.8.3. 底层资源的访问 3.8.4. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.9.1. 使用Singleton-helper类 4. 资源 4.1. 简介 4.2. Resource 接口 4.3. 内置 Resource 实现 4.3.1. UrlResource 4.3.2. ClassPathResource 4.3.3. FileSystemResource 4.3.4. ServletContextResource 4.3.5. InputStreamResource 4.3.6. ByteArrayResource 4.4. ResourceLoader 4.5. ResourceLoaderAware 接口 4.6. 把Resource作为属性来配置 4.7. Application context 和Resource 路径 4.7.1. 构造application context 4.7.2. Application context构造器中资源路径的通配符 4.7.3. FileSystemResource 提示 5. 校验,数据绑定,BeanWrapper,与属性编辑器 5.1. 简介 5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. Spring的AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点(pointcut) 6.2.4. 声明通知 6.2.5. 引入(Introductions) 6.2.6. 切面实例化模型 6

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值