Spring 容器被包含在web容器里面的
所以,要让你的Spring应用使用配置在web容器里面的jndi资源,比如数据库连接,必须采用以下步骤,我们这里以tomcat作为web容器的例子
(1) 在你的应用里面使用资源
比如以下代码中,注入了 catalogSessionFactory 资源
- /**
- *
- * Description:
- *
- * @author charles.wang
- * @created Mar 19, 2012 1:30:38 PM
- *
- */
- @Repository("homepageHotCategoryDao")
- public class HotCategoryDaoImpl implements IHotCategoryDao {
- private Logger logger=LoggerFactory.getLogger(HotProductDaoImpl.class);
- @Resource(name = "catalogSessionFactory")
- SessionFactory sessionFactory;
- /* (non-Javadoc)
- * @see com.bleum.canton.homepage.dao.IHotCategoryDao#addHotCategory(com.bleum.canton.homepage.entity.HotCategory)
- */
- @Transactional
- public void addHotCategory(HotCategory pHotCategory) throws HibernateException {
- // TODO Auto-generated method stub
- Session session = sessionFactory.getCurrentSession();
- session.save(pHotCategory);
- session.flush();
- }
- /* (non-Javadoc)
- * @see com.bleum.canton.homepage.dao.IHotCategoryDao#findTop6HotCategoryIds()
- */
- @Transactional
- public List<String> findTopHotCategoryIds(int number) {
- if(number<=0){
- if(logger.isDebugEnabled()){
- logger.debug("the number must be non-negative");
- }
- return null;
- }
- // TODO Auto-generated method stub
- Session session = sessionFactory.getCurrentSession();
- String findHotCategories ="FROM HotCategory";
- Query query=session.createQuery(findHotCategories);
- if( (query.list()==null ) || (query.list().size()==0) )
- return null;
- List<HotCategory> hotCategories = query.list();
- if(hotCategories.size()<number){
- if(logger.isDebugEnabled()){
- logger.debug("we don't have enough hot categories to display ,it must be at least 3");
- }
- return null;
- }
- List<String> topHotCategoryIds = new ArrayList<String> ();
- for(int i=0;i<number;i++){
- //top3HotProductIds.add(hotProducts.get(i).getProductId());
- topHotCategoryIds.add(hotCategories.get(i).getCategoryId());
- }
- return topHotCategoryIds;
- }
- /* (non-Javadoc)
- * @see com.bleum.canton.homepage.dao.IHotCategoryDao#updateHotCategory(com.bleum.canton.homepage.entity.HotCategory)
- */
- @Transactional
- public void updateHotCategory(HotCategory pHotCategory) {
- // TODO Auto-generated method stub
- Session session = sessionFactory.getCurrentSession();
- session.update(pHotCategory);
- session.flush();
- }
- /* (non-Javadoc)
- * @see com.bleum.canton.homepage.dao.IHotCategoryDao#findHotCategoryById(int)
- */
- @Transactional
- public HotCategory findHotCategoryById(int pHotCategoryId) {
- // TODO Auto-generated method stub
- Session session = sessionFactory.getCurrentSession();
- String findByIDHQL = "from HotCategory as p WHERE p.id=:id";
- Query query =session.createQuery(findByIDHQL);
- query.setInteger("id", pHotCategoryId);
- if( (query.list()==null ) || (query.list().size()==0) )
- return null;
- return (HotCategory)query.list().get(0);
- }
- /* (non-Javadoc)
- * @see com.bleum.canton.homepage.dao.IHotCategoryDao#deleteHotCategoryById(int)
- */
- @Transactional
- public void deleteHotCategoryById(int pHotCategoryId) throws HibernateException {
- // TODO Auto-generated method stub
- Session session = sessionFactory.getCurrentSession();
- HotCategory deleteHotCategory = this.findHotCategoryById(pHotCategoryId);
- session.delete(deleteHotCategory);
- session.flush();
- }
- }
而这个资源需要在Spring配置文件中声明,不难发现,他其实引用了catalogDataSource数据源资源
- <bean id="catalogSessionFactory" parent="xsessionFactory">
- <property name="dataSource" ref="catalogDataSource" />
- <property name="packagesToScan">
- <list>
- <value>com.bleum.canton.itempage.entity</value>
- <value>com.bleum.canton.homepage.entity</value>
- </list>
- </property>
- </bean>
这个catalogDataSource肯定最终是配置在web容器里面的,所以我们先假想定义一个Spring的jndi,并且在 web.xml里面配置好hook ,注意,这里的jndi并不是真实的web容器的jndi,而是Spring 容器的jndi,它从WEB-INF/web.xml中获得引用
- <!-- Load Data Sources by JNDI -->
- <jee:jndi-lookup id="estoreDataSource" jndi-name="jdbc/Canton_Estore_DB" />
- <jee:jndi-lookup id="caDataSource" jndi-name="jdbc/Canton_CA_DB" />
- <jee:jndi-lookup id="catalogDataSource" jndi-name="jdbc/Canton_Catalog_DB" />
- <jee:jndi-lookup id="omsDataSource" jndi-name="jdbc/Canton_OMS_DB" />
- <jee:jndi-lookup id="paymentDataSource" jndi-name="jdbc/Canton_Payment_DB" />
web.xml中会声明这些jndi引用的"钩子”
- <!-- JNDI Resource Refer -->
- <resource-ref>
- <description>Canton Estore Data Source</description>
- <res-ref-name>jdbc/Canton_Estore_DB</res-ref-name>
- <res-type>javax.sql.XADataSource</res-type>
- <res-auth>Container</res-auth>
- </resource-ref>
- <resource-ref>
- <description>Canton CA Data Source</description>
- <res-ref-name>jdbc/Canton_CA_DB</res-ref-name>
- <res-type>javax.sql.XADataSource</res-type>
- <res-auth>Container</res-auth>
- </resource-ref>
- <resource-ref>
- <description>Canton Catalog Data Source</description>
- <res-ref-name>jdbc/Canton_Catalog_DB</res-ref-name>
- <res-type>javax.sql.XADataSource</res-type>
- <res-auth>Container</res-auth>
- </resource-ref>
- <resource-ref>
- <description>Canton OMS Data Source</description>
- <res-ref-name>jdbc/Canton_OMS_DB</res-ref-name>
- <res-type>javax.sql.XADataSource</res-type>
- <res-auth>Container</res-auth>
- </resource-ref>
- <resource-ref>
- <description>Canton Payment Data Source</description>
- <res-ref-name>jdbc/Canton_Payment_DB</res-ref-name>
- <res-type>javax.sql.XADataSource</res-type>
- <res-auth>Container</res-auth>
- </resource-ref>
而这些与此同时,web容器上,也已经配置好了真实的jndi资源,见$CATALINA_HOME/conf/server.xml
- <GlobalNamingResources>
- <!-- Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/-->
- <!-- Data Sources Configuration for Canton -->
- <!-- estore -->
- <Resource auth="Container" driverClassName="oracle.jdbc.xa.client.OracleXADataSource" factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" maxActive="5" maxIdle="5" maxWait="-1" name="jdbc/Canton_Estore_DB" password="Canton_Estore_QA" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.129.14:15210:ora11g" username="Canton_Estore_QA"/>
- <Resource auth="Container" driverClassName="oracle.jdbc.xa.client.OracleXADataSource" factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" maxActive="5" maxIdle="5" maxWait="-1" name="jdbc/Canton_CA_DB" password="Canton_CA_QA" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.129.14:15210:ora11g" username="Canton_CA_QA"/>
- <Resource auth="Container" driverClassName="oracle.jdbc.xa.client.OracleXADataSource" factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" maxActive="5" maxIdle="5" maxWait="-1" name="jdbc/Canton_Catalog_DB" password="Canton_Catalog_QA" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.129.14:15210:ora11g" username="Canton_Catalog_QA"/>
- <Resource auth="Container" driverClassName="oracle.jdbc.xa.client.OracleXADataSource" factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" maxActive="5" maxIdle="5" maxWait="-1" name="jdbc/Canton_OMS_DB" password="Canton_OMS_QA" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.129.14:15210:ora11g" username="Canton_OMS_QA"/>
- <Resource auth="Container" driverClassName="oracle.jdbc.xa.client.OracleXADataSource" factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" maxActive="5" maxIdle="5" maxWait="-1" name="jdbc/Canton_Payment_DB" password="Canton_Payment_QA" type="javax.sql.DataSource" url="jdbc:oracle:thin:@192.168.129.14:15210:ora11g" username="Canton_Payment_QA"/>
- </GlobalNamingResources>
那么谁来充当web.xml里面的钩子以及web容器上真实的资源之间的粘合剂呢,在tomcat中,我们用的就是META-INF/context.xml,这个文件,才吧项目中的jndi的需求和真正容器上实际提供的jndi资源结合了起来
- <?xml version="1.0" encoding="UTF-8"?>
- <Context>
- <ResourceLink global="jdbc/Canton_Estore_DB" name="jdbc/Canton_Estore_DB" type="javax.sql.DataSource" />
- <ResourceLink global="jdbc/Canton_CA_DB" name="jdbc/Canton_CA_DB" type="javax.sql.DataSource" />
- <ResourceLink global="jdbc/Canton_Catalog_DB" name="jdbc/Canton_Catalog_DB" type="javax.sql.DataSource" />
- <ResourceLink global="jdbc/Canton_OMS_DB" name="jdbc/Canton_OMS_DB" type="javax.sql.DataSource" />
- <ResourceLink global="jdbc/Canton_Payment_DB" name="jdbc/Canton_Payment_DB" type="javax.sql.DataSource" />
- </Context>
本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/840696,如需转载请自行联系原作者