您的位置:首页 > 编程语言 > Java开发

如何让 Spring 应用使用web 容器的JNDI 资源

2012-04-21 17:39 561 查看
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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Tomcat JNDI