- 浏览: 974071 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
qq_15946053:
基于spring的项目要导出成jar怎么做呢用eclipse的 ...
Spring项目导出可运行的JAR -
flyfeifei66:
baseservice、dao代码是同一个,但是实例配置多个, ...
Spring通过父类注入公用属性的技巧 -
yuechao4039:
写得不错,望楼主再接再厉
Spring中配置和读取多个Properties文件 -
xinglianxlxl:
psubscribe对我有用
Jedis的Publish/Subscribe功能的运用 -
Fenix87:
js中怎么调用配置文件的参数呢
Spring中配置和读取多个Properties文件
Spring的JNDI数据源连接池配置示例及Spring对JNDI实现分析
- 博客分类:
- Spring
个人学习参考所用,勿喷!
在使用 Tomcat服务器 + SpringFramework 进行JavaEE项目的开发部署的时候可以在Tomcat的配置文件中进行JDBC数据源的配置,具体步骤如下(这里省略了工程的建立步骤):
1) 添加如下代码到tomcat的conf目录下的server.xml中:
<Context> <Resource name="jdbc/demoDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/demo" username="root" password="123" maxActive="50" maxIdle="30" maxWait="10000" /> </Context>
完成上述步骤数据源的连接池配置已经完成,但是为了提高项目的可移植性,最好将上述第二步的内容放入到工程的META-INF目录的context.xml中(这个文件需要自行建立):
<?xml version="1.0" encoding="UTF-8"?> <Context> <Resource name="jdbc/demoDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/demo" username="root" password="123" maxActive="50" maxIdle="30" maxWait="10000" /> </Context>
2)在Spring的配置文件,如applicationContext.xml中配置配置如下内容:
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/demoDB</value> </property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref bean="dataSource" /> </property> </bean> <!-- 这里是自定义的数据库基础操作类 --> <bean id="sqlBaseDAO" class="demo.BaseDAOImpl"> <property name="jdbcTemplate"> <ref bean="jdbcTemplate" /> </property> </bean> </beans>
3)建立数据库基础操作类 BaseDAOImpl
接口代码:
public interface BaseDAO { public List<Map<String, Object>> select(String sql); public void update(String how); public void insert(Object obj); public void insert(String sql); public void save(String sql); public void edit(String sql); public void execute(String sql, PreparedStatementCallback callback); public void delete(String sql); public void insertObjects(String[] sqls); public Connection getConnection() throws Exception; }
实现类代码:
public class BaseDAOImpl implements BaseDAO { private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate){ this.jdbcTemplate = jdbcTemplate; } public void insert(Object obj) { } public void insert(String sql) { jdbcTemplate.execute(sql); } public void insertObjects(String[] sqls) { jdbcTemplate.batchUpdate(sqls); } public List<Map<String, Object>> select(String sql) { return jdbcTemplate.queryForList(sql); } public void update(String how) { jdbcTemplate.update(how); } public void delete(String sql) { if (sql == null) { return; } jdbcTemplate.execute(sql); } public void edit(String sql) { if (sql == null) { return; } jdbcTemplate.execute(sql); } public void execute(String sql, PreparedStatementCallback callback) { jdbcTemplate.execute(sql, callback); } public void save(String sql) { if (sql == null) { return; } jdbcTemplate.execute(sql); } public Connection getConnection() throws Exception { Connection conn = jdbcTemplate.getDataSource().getConnection(); return conn; } }
这里存在一个疑问:
运行如下代码:
public static void main(String[] args) { org.springframework.jndi.JndiObjectFactoryBean jofb = new org.springframework.jndi.JndiObjectFactoryBean(); javax.sql.DataSource ds = (javax.sql.DataSource)jofb; org.springframework.jdbc.core.JdbcTemplate jTemplate = new org.springframework.jdbc.core.JdbcTemplate(); jTemplate.setDataSource(ds); }
会报告如下的错误:
Exception in thread "main" java.lang.ClassCastException: org.springframework.jndi.JndiObjectFactoryBean cannot be cast to javax.sql.DataSource
从JndiObjectFactoryBean的源码中也可以看到,JndiObjectFactoryBean的父类或所继承的接口都没有继承javax.sql.DataSource接口,所以一下的配置中:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/portalDataService</value> </property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref bean="dataSource" /> </property> </bean>
对org.springframework.jdbc.core.JdbcTemplate的dataSource属性的注入为何能够成功?
带着这样的疑问去iteye中提问,没有得到详细的解答,但是iteye的提示功能似乎很不错,在问题的下方给出了相关内容参考提示,进入到《从源代码解读spring之DataSource实现和FactoryBean模式》这个帖子中,看完以后大受启发。一下是从这篇帖子摘抄出来的内容:
再看源码后发现,JndiObjectFactoryBean实现了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里面。
好吧,也许上面org.springframework.beans.factory.FactoryBean的注释看起来像家长教育孩子该怎么怎么,那么Spring到底是怎么实现这种思想的呢?参考《Spring技术内幕》中2.5.3节对FactoryBean的实现的讲解,结合Spring的源码可以看到:
常见的工厂Bean是怎样实现的,这些FactoryBean为应用生成需要的对象,这些对象往往是经过特殊处理的,比如像 ProxyFactoryBean 这样的特殊 Bean。FactoryBean 的生产特性是在getBean中起作用的,我们看到下面的调用:
再来看FactoryBean特性的实现:
//该方法在org.springframework.beans.factory.support.AbstractBeanFactory类中 protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. // 如果这里不是对FactoryBean的调用,那么结束处理。 if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); //这里从FactoryBean中得到bean。 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; } //该方法在org.springframework.beans.factory.support.FactoryBeanRegistrySupport类中 protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); } return (object != NULL_OBJECT ? object : null); } } else { return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); } } //该方法在org.springframework.beans.factory.support.FactoryBeanRegistrySupport类中 private Object doGetObjectFromFactoryBean( final FactoryBean factory, final String beanName, final boolean shouldPostProcess) throws BeanCreationException { Object object; //这里调用factory的getObject方法来从FactoryBean中得到bean。 try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { return factory.getObject(); } }, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { object = factory.getObject(); } } catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); } // Do not accept a null value for a FactoryBean that's not fully // initialized yet: Many FactoryBeans just return null then. if (object == null && isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException( beanName, "FactoryBean which is currently in creation returned null from getObject"); } if (object != null && shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex); } } return object; }
这里返回的已经是作为工厂的 FactoryBean 生产的产品,并不是 FactoryBean 本身。这种FactoryBean的机制可以为我们提供一个很好的封装机制,比如封装Proxy、RMI、JNDI等。经过对FactoryBean实现过程的原理分析,相信读者会对getObject方法有很深刻的印象。这个方法就是主要的FactoryBean 的接口,需要实现特定的工厂的生产过程,至于这个生产过程是怎样和IoC容器整合的,就是我们在上面分析的内容。
那么返回的类型是怎么确定为javax.sql.DataSource类型的呢?回头再看在context.xml中的数据源配置可以看到:
type="javax.sql.DataSource"
这样一句。然后在去细看JndiObjectFactoryBean类中的afterPropertiesSet方法的具体代码所以一切都明了了。
综上所述,这里主要还是要对Spring的FactoryBean模式的理解最为重要。
评论
朋友,谢谢你的谬赞!
发表评论
-
Spring项目导出可运行的JAR
2013-09-05 20:01 16306一、在使用MAVEN的打包插件。 1.背景 ... -
Spring Security3实践总结
2013-07-22 18:12 19337在线项目最近要对管理系统进行细粒度的权限控 ... -
Spring中配置和读取多个Properties文件
2013-05-31 16:45 61609一个系统中通常会存在如下一些以Properties形式存在 ... -
Spring多数据源的配置和使用(2)
2012-11-22 11:40 18765本文以Spring2.5 + Hibernat ... -
Spring定时任务的多种使用方法总结
2012-08-04 17:34 10454这里使用的是Spring2.5,需要的jar包:sprin ... -
Spring多数据源的配置和使用(1)
2012-08-04 14:51 22664最近开发一个数据同步的小功能,需要从A主机的Ora ... -
Spring通过父类注入公用属性的技巧
2012-06-19 13:22 29864XML配置方式提取父类 在 ... -
Spring3 MVC
2012-04-24 17:16 0个人学习参考所用,勿喷! 1.搭建一个基于S ... -
Spring3 MVC的最佳实践和理解(9)
2012-04-25 09:10 2583个人学习参考所用,勿喷! 9.创建一个资源多种实现的 ... -
Spring3 MVC的最佳实践和理解(8)
2012-04-25 09:10 2329个人学习参考所用,勿喷! 8.Bean的注解式 ... -
Spring3 MVC的最佳实践和理解(7)
2012-04-25 09:09 4170个人学习参考所用, ... -
Spring3 MVC的最佳实践和理解(6)
2012-04-25 09:09 2057个人学习参考所用, ... -
Spring3 MVC的最佳实践和理解(5)
2012-04-24 17:01 22098个人学习参考所用, ... -
Spring3 MVC的最佳实践和理解(4)
2012-04-24 16:59 4838个人学习参考所用,勿喷! 4.区域解析和外部化区 ... -
Spring3 MVC的最佳实践和理解(3)
2012-04-24 16:56 4526个人学习参考所用,勿喷! 3.使用拦截器 Sp ... -
Spring3 MVC的最佳实践和理解(2)
2012-04-24 16:55 5079个人学习参考所用,勿 ... -
Spring3 MVC的最佳实践和理解(1)
2012-04-24 16:53 3815个人学习参考所用,勿喷! 1.搭建一个基 ... -
Spring RESTful服务接收和返回JSON最佳实践
2012-04-16 17:13 108618个人学习参考所用,勿喷! 返回JSON ... -
Spring属性注入和构造函数注入参考
2012-02-25 23:23 4421个人学习参考所用,勿喷! 1.Pojo如下: ...
相关推荐
基于C++开发的WEB服务器,支持C/C++、Python、Java等多语言混合开发WEB应用
基于STM8单片机的编程实例,可供参考学习使用,希望对你有所帮助
基于STM8单片机的编程实例,可供参考学习使用,希望对你有所帮助
该靶场仅供学习使用!
电影详情链接 图片链接 影片中文名 影片外国名 评分 评价人数 概况 相关信息 https://movie.douban.com/subject/1292052/ https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg 肖申克的救赎 The Shawshank Redemption 9.7 2529468 希望让人自由 导演: 弗兰克·德拉邦特 Frank Darabont 主演: 蒂姆·罗宾斯 Tim Robbins ... 1994 美国 犯罪 剧情 https://movie.douban.com/subject/1291546/ https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2561716440.jpg 霸王别姬 9.6 1880353 风华绝代 导演: 陈凯歌 Kaige Chen 主演: 张国荣 Leslie Cheung 张丰毅 ........
汽车中间件市场调研报告:2023年全球汽车中间件市场销售额达到了78亿美元 在数字化转型的浪潮中,汽车中间件作为连接硬件与软件的关键桥梁,正引领着汽车行业的新一轮变革。随着全球汽车产业的快速发展,中间件市场规模持续扩大,展现出前所未有的增长潜力。然而,面对复杂多变的市场环境和不断涌现的新技术,企业如何精准把握市场脉搏,实现可持续发展?本文将深入探讨全球及中国汽车中间件市场的现状、趋势及竞争格局,为您揭示咨询的重要性。 市场概况: 根据QYResearch(恒州博智)的统计及预测,2023年全球汽车中间件市场销售额达到了78亿美元(约7803百万美元),预计2030年将达到156亿美元(约15630百万美元),年复合增长率(CAGR)为10.3%(2024-2030)。这一数据不仅彰显了中间件市场的强劲增长动力,也预示着未来巨大的市场空间。 技术创新与趋势: 随着自动驾驶、车联网等技术的不断发展,汽车中间件正面临着前所未有的技术挑战与机遇。新一代中间件需要具备更高的实时性、更低的延迟以及更强的数据处理能力,以满足复杂多变的汽车应用场景。同时,云计算、大数据、人工智能等技术的融合应用,将进
python语言mp3pl爬虫程序代码QZQ
# 小语种字体TTF文件转PNG图片的方法 ## 准备工作 1. 下载python3.9,推荐3.6~3.9,几个依赖包在这个版本运行的好。 2. 下载 FontForge-mingw-w64 ,可自行下载,或从文末打包好的工具包直接使用。 3. 下载需要导出的字体ttf文件,最好先装在本机系统上。 ## 导出方法 1. 把 `tts2png2.py` 文件复制到软件的bin目录下。 2. 修改 `tts2png2.py` 文件中的字体路径,注意Windows用双斜杠。 3. 从bin目录打开终端(管理员模式启动)。 4. 运行脚本 `./ffpython .\tts2png2.py`。
在21世纪的科技浪潮中,人工智能(AI)无疑是最为耀眼的明星之一,它以惊人的速度改变着我们的生活、工作乃至整个社会的运行方式。而在人工智能的广阔领域中,大模型(Large Models)的崛起更是开启了智能技术的新纪元,引领着AI向更加复杂、高效、智能的方向发展。本文将深入探讨人工智能大模型的内涵、技术特点、应用领域以及对未来的影响。 一、人工智能大模型的内涵 人工智能大模型,顾名思义,是指具有庞大参数规模和数据处理能力的AI模型。这些模型通过深度学习算法,在海量数据上进行训练,能够学习到丰富的知识表示和复杂的模式识别能力。与传统的小型或中型模型相比,大模型在理解自然语言、生成高质量内容、进行跨模态信息处理等方面展现出前所未有的优势。它们不仅能够执行特定的任务,如图像识别、语音识别,还能进行创造性的工作,如文本生成、音乐创作,甚至在某些情况下展现出接近或超越人类的智能水平。 二、技术特点 海量数据与高效训练:大模型依赖于庞大的数据集进行训练,这些数据涵盖了广泛的主题和情境,使得模型能够学习到丰富的语义信息和上下文理解能力。同时,高效的训练算法和硬件加速技术,如TPU(Tensor Processing Unit)和GPU,使得大规模模型的训练成为可能。 自注意力机制与Transformer架构:许多领先的大模型采用了Transformer架构,特别是其自注意力机制,这种设计使得模型在处理序列数据时能够捕捉到长距离依赖关系,极大地提高了模型的表达能力和泛化能力。 多任务学习与迁移学习:大模型通常具备多任务学习的能力,即在一次训练中同时学习多个任务,这有助于模型学习到更通用的知识表示。此外,迁移学习使得这些模型能够轻松适应新任务,只需少量额外数据或微调即可。
下垂控制-基于T型三电平逆变器的下垂控制,电压电流双闭环,采用LCL滤波,SPWM调制方式 1.提供simulink仿真源文件 2.提供下垂控制原理与下垂系数计算方法 3.中点平衡控制,电压电流双闭环控制 4.提供参考文献
城市选择器一个仿大众点评的城市快速选择器, 最少只需 一行 代码即可启动城市选择器, 支持页面样式修改,多元化自定义截屏 版本日志V0.4.6优化地理位置设置时有时会设置不成功问题修复其他若干问题修改UI默认主题色V0.4.5修改设置位置信息方式,由之前必须在打开页面之前获取位置信息改为允许用户在打开页面后设置位置信息,具体使用方式见 Step3简化配置项,不需要在AndroidManifest中再注册Activity,并默认隐藏titlebarV0.4.3修复更新数据库表结构后第一次进入会闪退问题V0.4.0数据库表结构修改,增加了高德地图citycode设置gps城市的api略有改动见 Step3V0.3.3紧急修复一个可能导致内存泄漏问题优化提高滑动检索效率隐藏下拉刷新labelV0.3.1在搜索框后面添加一个清空搜索框按钮修复搜索框中输入空格会搜索出全部城市问题修复搜索结果弹出框中文字在不同theme下显示不同颜色问题,现在已统一为黑色其他调用时参数合法性校验V0.3.0简化api调用形式,修改为Rx形式,见操作步骤
慢性病大数据分析处理慢性病项目
Multisim单片机资源单片机C语言程序设计实训100例提取方式是百度网盘分享地址
PMSM永磁同步电机最大转矩电流比MTPA控制仿真,弱磁控制仿真,前馈补偿仿真程序,详细解析教程文档。 这是一份非常完美的仿真文件及详细教程,从仿真效果图看转速、电流及转矩跟随非常稳定。 该算法架构包含如下模块: 1)SVPWM矢量控制模块 2)转速环PI调节器、电流环PI调节器; 3)MTPA调节器; 4)弱磁控制器; 5)前馈补偿; 一份该仿真的算法说明文档,每一步都有详细介绍如何搭建,包括环路参数怎么算,拿来做毕设或者学习都很方便; 几篇参考文献; 一篇作者自己写的算法总结,让你少走弯路; 两个视频;
手绘卡通儿童人物幼儿园教学课件模板
Simulink电动汽车仿真模型(包含行驶阻力模型,工作模式切模型,驾驶员模型,PID控制模块等,NEDC,CLTC工况仿真结果)东西很全
是一款全功能的备份软件,支持增量备份、差异备份、完全备份和同步备份,帮助用户轻松保护关键文件。支持多种存储选项,包括本地硬盘、USB驱动器、网络文件夹、云存储和 FTP 服务器等。 【使用方法】: 1. 下载并安装 Perfect Backup。 2. 打开软件,选择备份类型(增量、差异、完全或同步)。 3. 指定源文件和目标存储位置。 4. 设置备份计划,选择备份频率。 5. 点击“开始备份”,执行备份任务。
基于STM8单片机的编程实例,可供参考学习使用,希望对你有所帮助
资源描述: HTML5实现好看的创意房屋设计公司网页源码,好看的创意房屋设计公司网页源码,创意房屋设计公司网页源码模板,HTML创意房屋设计公司网页源码,内置酷炫的动画,界面干净整洁,页面主题,全方位介绍内容,可以拆分多个想要的页面,可以扩展自己想要的,注释完整,代码规范,各种风格都有,代码上手简单,代码独立,可以直接运行使用。也可直接预览效果。 资源使用: 点击 index.html 直接查看效果