- 浏览: 296925 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
wangweiying123:
import com.sse.monitor.bean.Mes ...
一个项目看java TCP/IP Socket编程(1.3版) -
daxiaoli123:
求源码 448485223@qq.com
一个项目看java TCP/IP Socket编程(1.3版) -
jeromexf:
楼主,求源码,万分感谢(jeromexf@gmail.com) ...
一个项目看java TCP/IP Socket编程(1.3版) -
cuishen:
注意: 网上有人说IE8以下不支持Max-Age, 上面的代码 ...
Response Header Set-Cookie difference in cross browser -
zhunengfei:
刚接触socket,不是太明白,楼主的例子里面工具给的不是很全 ...
一个项目看java TCP/IP Socket编程(1.3版)
大家平日使用spring + hibernate做项目的时候大概都接触过下面的spring配置代码:
下面是使用普通的jdbc驱动获得DataSource的配置
下面是通过JNDI获得的DataSource的配置,只要将上面的id为"dataSource"的bean换成下面的配置就行了
配置很简单,使用也非常方便,spring毫不挑食,不管是jdbc版的DataSource也好,是JNDI版的也好,它都能接受,那这个兼容性是怎么做到的呢??现在从源代码入手来一探究竟:
1. 先看看jdbc版的DataSource - org.springframework.jdbc.datasource.DriverManagerDataSource
再看看这个AbstractDataSource:
哈哈,原来DriverManagerDataSource是javax.sql.DataSource的实现类,那做为bean注入给sessionFactory真是无可厚非
我们再看看它内部的实现细节
哈哈,这代码是不是再熟悉也不过啦?原来DriverManagerDataSource实现了javax.sql.DataSource接口,本质是对jdbc连接数据库的简单封装
2. 接下来看看JNDI版的DataSource - org.springframework.jndi.JndiObjectFactoryBean
追溯JndiObjectFactoryBean的父类和实现的接口以及父类的父类,都和javax.sql.DataSource接口八竿子打不着,没有一点点渊源,oh,my God! 这怎么可能!?完全不相干的对象怎么能够被注入?这完全有悖java的精神!但事实摆在眼前,测试是完全通过的!静下心来,我注意到了JndiObjectFactoryBean实现了FactoryBean接口,一直以来脑子里对FactoryBean模式感到有点模糊,不能完全领会其本质,难道真的是这里面有文章??好,借此机会,好好研究下FactoryBean接口,下面是org.springframework.beans.factory.FactoryBean源代码里一段注释:
翻译过来是说:所有实现FactoryBean接口的类都被当作工厂来使用,而不是简单的直接当作bean来使用,FactoryBean实现类里定义了要生产的对象,并且由FactoryBean实现类来造该对象的实例,看到这里聪明的你大概已经能猜出个八九不离十了吧
我们回过头来看看JndiObjectFactoryBean的实现细节
现在揭晓谜底:很简单,对于JndiObjectFactoryBean对象,spring IOC容器启动时确实造了它的对象,只不过这时是工厂本身,spring会自动调用工厂里的afterPropertiesSet()方法去造真正需要的bean,然后调用getObject()和getObjectType()方法返回已造好的对象和类型,再将其准确的注入依赖它的其他bean里面,所以并没有违背java的精神!
有兴趣也可以看看org.springframework.orm.hibernate3.LocalSessionFactoryBean,它也实现了FactoryBean接口,内部实现如出一辙,只不过它担负的重任不是造JNDI object,而是要造SessionFactory对象
下面是使用普通的jdbc驱动获得DataSource的配置
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"><value>oracle.jdbc.OracleDriver</value></property> <property name="url"><value>jdbc:oracle:thin:@caij-b815c8aab6:1521:cui</value></property> <property name="username"><value>cuishen</value></property> <property name="password"><value>cuishen</value></property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="mappingResources"><list> <value>com/cuishen/testDao/pojo/Test.hbm.xml</value> </list></property> <property name="hibernateProperties"><props> <prop key="dialect">org.hibernate.dialect.Oracle9Dialect</prop> <prop key="connection.autocommit">true</prop> </props></property> <property name="dataSource"><ref local="dataSource"/></property> </bean> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"><ref local="sessionFactory"/></property> </bean> <bean id="dao" class="com.conserv.dao.impl.HibernateDaoImpl" init-method="init" destroy-method="destroy"> <property name="transactionManager"><ref local="txManager"/></property> <property name="dialect"><value>Oracle9</value></property> </bean>
下面是通过JNDI获得的DataSource的配置,只要将上面的id为"dataSource"的bean换成下面的配置就行了
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="cs" /> </bean>
配置很简单,使用也非常方便,spring毫不挑食,不管是jdbc版的DataSource也好,是JNDI版的也好,它都能接受,那这个兼容性是怎么做到的呢??现在从源代码入手来一探究竟:
1. 先看看jdbc版的DataSource - org.springframework.jdbc.datasource.DriverManagerDataSource
public class DriverManagerDataSource extends AbstractDataSource
再看看这个AbstractDataSource:
public abstract class AbstractDataSource implements javax.sql.DataSource
哈哈,原来DriverManagerDataSource是javax.sql.DataSource的实现类,那做为bean注入给sessionFactory真是无可厚非
我们再看看它内部的实现细节
return DriverManager.getConnection(url, props);
哈哈,这代码是不是再熟悉也不过啦?原来DriverManagerDataSource实现了javax.sql.DataSource接口,本质是对jdbc连接数据库的简单封装
2. 接下来看看JNDI版的DataSource - org.springframework.jndi.JndiObjectFactoryBean
public class JndiObjectFactoryBean extends JndiObjectLocator implements FactoryBean
追溯JndiObjectFactoryBean的父类和实现的接口以及父类的父类,都和javax.sql.DataSource接口八竿子打不着,没有一点点渊源,oh,my God! 这怎么可能!?完全不相干的对象怎么能够被注入?这完全有悖java的精神!但事实摆在眼前,测试是完全通过的!静下心来,我注意到了JndiObjectFactoryBean实现了FactoryBean接口,一直以来脑子里对FactoryBean模式感到有点模糊,不能完全领会其本质,难道真的是这里面有文章??好,借此机会,好好研究下FactoryBean接口,下面是org.springframework.beans.factory.FactoryBean源代码里一段注释:
/** * Interface to be implemented by objects used within a BeanFactory * that are themselves factories. If a bean implements this interface, * it is used as a factory, not directly as a bean. * * <p><b>NB: A bean that implements this interface cannot be used * as a normal bean.</b> A FactoryBean is defined in a bean style, * but the object exposed for bean references is always the object * that it creates. */
翻译过来是说:所有实现FactoryBean接口的类都被当作工厂来使用,而不是简单的直接当作bean来使用,FactoryBean实现类里定义了要生产的对象,并且由FactoryBean实现类来造该对象的实例,看到这里聪明的你大概已经能猜出个八九不离十了吧
我们回过头来看看JndiObjectFactoryBean的实现细节
private Object jndiObject; /** * Look up the JNDI object and store it. * 广义上说是造对象的过程,就本例而言,是通过JNDI获得DataSource对象 */ public void afterPropertiesSet() throws IllegalArgumentException, NamingException { super.afterPropertiesSet(); if (this.proxyInterface != null) { if (this.defaultObject != null) { throw new IllegalArgumentException( "'defaultObject' is not supported in combination with 'proxyInterface'"); } // We need a proxy and a JndiObjectTargetSource. this.jndiObject = JndiObjectProxyFactory.createJndiObjectProxy(this); } else { if (!this.lookupOnStartup || !this.cache) { throw new IllegalArgumentException( "Cannot deactivate 'lookupOnStartup' or 'cache' without specifying a 'proxyInterface'"); } if (this.defaultObject != null && getExpectedType() != null && !getExpectedType().isInstance(this.defaultObject)) { throw new IllegalArgumentException("Default object [" + this.defaultObject + "] of type [" + this.defaultObject.getClass().getName() + "] is not of expected type [" + getExpectedType().getName() + "]"); } // Locate specified JNDI object. this.jndiObject = lookupWithFallback(); } } /** * Return the singleton JNDI object. * 返回JNDI对象(DataSource对象) */ public Object getObject() { return this.jndiObject; } public Class getObjectType() { if (this.proxyInterface != null) { return this.proxyInterface; } else if (this.jndiObject != null) { return this.jndiObject.getClass(); } else { return getExpectedType(); } }
现在揭晓谜底:很简单,对于JndiObjectFactoryBean对象,spring IOC容器启动时确实造了它的对象,只不过这时是工厂本身,spring会自动调用工厂里的afterPropertiesSet()方法去造真正需要的bean,然后调用getObject()和getObjectType()方法返回已造好的对象和类型,再将其准确的注入依赖它的其他bean里面,所以并没有违背java的精神!
有兴趣也可以看看org.springframework.orm.hibernate3.LocalSessionFactoryBean,它也实现了FactoryBean接口,内部实现如出一辙,只不过它担负的重任不是造JNDI object,而是要造SessionFactory对象
评论
5 楼
firefly1314
2010-01-16
提出问题->分析问题->解决问题
lz步步深入,分析的很透彻。向lz学习,不浮于问题表面。
最近对spring的注入一头雾水,还需深入,继续学习ing~~~~
lz步步深入,分析的很透彻。向lz学习,不浮于问题表面。
最近对spring的注入一头雾水,还需深入,继续学习ing~~~~
4 楼
haokong
2010-01-16
有点意思,学习了,lz再接再厉啊。
看来什么都要追根问底啊。
看来什么都要追根问底啊。
3 楼
shanfeng1
2009-11-11
看来咱层次还没上来
2 楼
xiaogu2008
2009-10-09
看了我不困
1 楼
xiaogu2008
2009-10-09
分析的相当精彩。
发表评论
-
Response Header Set-Cookie difference in cross browser
2014-07-02 21:26 8391如果你项目中需要在server端把cookie写回client ... -
struts1 redirect issue
2014-05-08 23:04 1339近日突然发现struts1 的redirect有很大的限制,它 ... -
Cookie 和 sessionStorage的区别
2014-03-18 23:21 1546expire设为null的cookie是session sco ... -
http https get post 的区别,定义/安全性/性能
2014-02-20 18:19 14639HTTP / HTTPS request 的 get / po ... -
struts1的tiles导致的response cache无法禁止的issue
2014-02-15 00:13 1488近日struts 1项目中遇到一个很怪异的问题,项目中的所有. ... -
XFS攻击一例
2013-08-13 17:50 5997XFS: Cross Frame Script (跨框架脚本) ... -
XSS攻击一例
2013-08-12 17:55 1773XSS 全称(Cross Site Scripting) 跨站 ... -
maven3 compile failed, class file not found issue
2013-07-16 18:31 1432今日maven3 build 老是失败,停在compile,报 ... -
maven plugin for eclipse 3.6+
2013-07-04 18:24 1160this for eclipse 3.6 down http: ... -
JQuery异步提交表单在Firefox button onclick事件下可能导致重复提交
2013-06-04 19:58 4857当我们处理button的onclick事件时,在onclick ... -
AJAX JQuery 提交表单乱码问题解决方案
2012-10-16 13:59 13667最近遇到AJAX/JQuery 提交form表单出现乱码的问题 ... -
hibernate多对多级联删除总结
2010-04-02 07:46 3569A. 应用场景: 一个简单的权限系统的例子: 有三张主表: ... -
iBATIS一对多/多对多N+1问题解决方案
2009-12-08 17:53 13130对于iBATIS一对多/多对多的问题,传统的办法是在一对多/多 ... -
最原始的O/R Mapping,比hibernate轻的多
2009-12-04 17:44 3518hibernate的O/R Mapping确实 ... -
Apache_WebLogic9.2.2安装及集群、SSL配置手册
2009-10-09 17:27 1545Apache_WebLogic9.2.2安装及集群、SSL配置 ... -
浅析Java web程序之客户端和服务器端交互原理
2009-09-16 21:18 47691. 协议 a. TCP/IP整体构 ... -
spring aop 事务配置总结
2009-08-06 13:47 5587以下配置基于spring 1x ... -
从源代码解读hibernate之数据库连接
2009-07-17 15:59 3755大家都知道hibernate是在JDBC基础上的封装,那么它的 ... -
AIX环境下JDK1.5 + WebLogic9.2.2安装配置手册
2009-01-22 13:15 2364项目中用到: 服务器:IBM 64位 小型机 操作系统:AI ... -
从源代码解读spring IOC容器
2008-09-19 09:43 4010spring IOC容器(Inversion of Contr ...
相关推荐
本篇文章将深入探讨Spring AOP的内部实现,以及如何通过源代码理解其DataSource实现和FactoryBean模式。 首先,让我们了解AOP的基本概念。AOP的核心思想是“切面”,它封装了特定的关注点,如日志记录、事务管理、...
总的来说,Spring通过`LocalSessionFactoryBean`实现对Hibernate的驱动,它将数据源、事务管理和配置信息集成在一起,创建出适应Spring管理的`SessionFactory`。这种集成方式使得开发者无需过多关注底层细节,可以...
在SpringBoot项目中,整合Mybatis-Plus并实现多数据源的动态切换,同时支持分页查询是一项常见的需求。以下将详细阐述这个过程中的关键步骤和技术要点。 首先,我们需要引入必要的Maven依赖。这里提到了四个关键...
在IT行业中,Spring Boot、MyBatis和Druid都是非常重要的技术组件,它们分别在微服务开发、数据库操作...通过这个源代码,你可以学习到如何在Spring Boot中灵活地管理和切换数据源,为不同的业务场景提供数据访问支持。
5. **使用多数据源**:在业务代码中,通过`@Autowired`和`@Qualifier`注解来指定使用哪个数据源。例如: ```java @Service public class UserService { @Autowired @Qualifier("primary") private ...
总结起来,通过SpringBoot、Mybatis-Plus和Druid,我们可以方便地实现双数据源配置,使得应用能同时处理MySQL和Oracle数据库的数据。在实际开发中,要根据业务场景灵活切换数据源,确保数据操作的正确性和效率。同时...
在Spring Boot应用中集成MyBatis并实现多数据源,是一种常见的需求,特别是在大型系统中,可能需要连接多个数据库以实现数据隔离或者读写分离。本文将详细介绍两种不同的实现方式,分别为静态添加和动态添加数据源。...
3. **配置数据源**:使用`@Configuration`和`@EnableJpaRepositories`注解来定义两个不同的`DataSource`,分别对应主库和从库。同时,使用`@Primary`标记主数据源。 ```java @Configuration public class ...
本篇将详细讲解如何在Spring Boot项目中结合Mybatis和Druid实现多数据源配置,以支持Oracle和MySQL两种数据库,并进行数据库的分离调试。 首先,我们要理解Spring Boot的自动配置机制。Spring Boot通过扫描`@...
本示例项目"springboot_mybatis 双数据源配置代码"提供了一个完整的解决方案,展示了如何在Spring Boot和MyBatis框架下配置和管理两个不同的数据源。下面将详细介绍这个项目的实现细节和相关的技术知识点。 首先,...
为了在业务代码中切换数据源,我们需要创建一个`AbstractRoutingDataSource`的实现类,它可以根据特定的条件选择要使用的数据源。 ```java @Configuration public class DynamicDataSource extends ...
本文将详细介绍如何在项目中整合iBatis与Spring,并通过一个学习程序的源代码分析其实现原理。 首先,理解iBatis的核心概念。iBatis将SQL语句与Java代码分离,通过XML或注解定义SQL映射文件,实现了SQL与代码的解耦...
本篇文章将深入探讨如何在Spring Boot项目中实现MyBatis的多数据源配置。 首先,我们要明白什么是多数据源。多数据源是指在一个应用程序中,可以同时连接并操作多个不同的数据库。这种需求通常出现在大型系统中,...
以上就是Spring Boot中结合MyBatis和Oracle配置双数据源的基本步骤。在实际开发中,还需要考虑事务管理、读写分离、路由策略等问题,但这里主要介绍了基础配置。通过这种方式,我们可以灵活地管理和操作多个数据库,...
本篇文章将详细讲解如何在Spring Boot项目中整合Mybatis和Druid,实现多数据源的配置和管理。 首先,我们来看“start-spring-boot”项目的核心概念。Spring Boot简化了Spring的初始化和配置,使得开发者能够快速...
Spring Boot以其自动化配置和简洁的编程模型而受到欢迎,而MyBatis则是一款优秀的持久层框架,它允许开发者直接编写SQL,实现了SQL与Java代码的深度融合。下面将详细介绍在Spring Boot中配置MyBatis以及实现多数据源...
接下来,我们需要在`@ConfigurationProperties`的帮助下,将数据源配置的属性值从`application.properties`或`application.yml`文件中读取,以提高代码的可维护性。例如: ```properties # application.properties ...
这个项目实例 `spring-boot-mybatis-mulidatasource` 可能包含了完整的代码结构,包括配置文件、数据源配置、MyBatis 配置、Service 和 DAO 层的实现。通过学习和分析这个实例,你可以深入理解如何在 Spring Boot ...
总结起来,Spring Boot 2.1.1与MyBatis的集成涉及了依赖引入、数据源配置、MyBatis配置、Mapper接口和XML映射文件的编写等多个环节。通过这种方式,我们可以轻松地利用Spring Boot的便利性和MyBatis的灵活性,实现...
当Spring Boot与MyBatis结合时,可以极大地提升开发效率,同时保持代码的简洁性。本文将深入探讨Spring Boot 2.1.3版本中集成MyBatis的相关知识点。 一、Spring Boot Starter MyBatis简介 Spring Boot Starter ...