如果您设置在server.xml中或context.xml中的数据库连接属性如果您设置在server

2019-05-13 00:52发布

我试图设置使用JNDI的春天Web应用程序的数据库连接属性。

我正在考虑两种方法如下:

方法1:

在Spring配置你可能有这样的事情:

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/facs"/>

然后,在你的webapp /META-INF/context.xml文件,你应该有类似的东西太多:

<?xml version='1.0' encoding='utf-8'?>

<!-- antiResourceLocking="true" -->
<Context path="/podd-apn"
         reloadable="true"
         cachingAllowed="false"
         antiResourceLocking="true"
         >

  <Resource name="jdbc/facs"              
            type="javax.sql.DataSource" username="${database.username}" password="${database.password}"
            driverClassName="org.postgresql.Driver" 
            url="${database.url}"
            maxActive="8" maxIdle="4"
            global="jdbc/facs" 
            />


</Context>

而在你的web.xml,你应该是这样的:

<!-- JNDI -->
  <resource-ref>
    <description>FACs Datasource</description>
    <res-ref-name>jdbc/facs</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref> 


方法2:

设置在这样的Spring上下文:

<jee:jndi-lookup id="dbDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />

您可以使用这样的事情在Tomcat的server.xml中声明JNDI资源:

<GlobalNamingResources>
  <Resource name="jdbc/DatabaseName" auth="Container" type="javax.sql.DataSource"
              username="dbUsername" password="dbPasswd"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="5" maxWait="5000"
              maxActive="120" maxIdle="5"
              validationQuery="select 1"
              poolPreparedStatements="true"/>
</GlobalNamingResources/>

和参考从Tomcat的网站的context.xml这样的JNDI资源:

<ResourceLink name="jdbc/DatabaseName"
   global="jdbc/DatabaseName"
   type="javax.sql.DataSource"/>


我的问题是在哪里是保持数据库性能的最佳地点? 他们应该被放置在server.xml中或context.xml中

另外,如果我有2个数据库,我应该用两个CONFIGS?

此外,它是最好的做法,直接将它们放置在任何的server.xml或context.xml中? 或者我需要通过Tomcat管理GUI控制台来配置?

谢谢!

Answer 1:

我更喜欢第三种方法,是以从最好的方法1方法2 通过user1016403描述 。

方法3

  1. 在保存数据库属性server.xml
  2. 引用server.xml从该web应用程序的数据库属性META-INF/context.xml

接近3个优点

虽然第一点出于安全原因是有用的第二点是从Web应用程序中引用服务器属性值是有用的,即使服务器属性值会发生变化。

从web应用的服务器上使用。此外脱钩资源定义可以跨各种复杂的组织,不同的团队在不同的层级/图层这样的配置可扩展:服务器管理员团队可以工作,而如果管理员共享相同的与开发人员团队发生冲突JNDI名称与开发商的每个资源。

方法3实施

定义JNDI名称jdbc/ApplicationContext_DatabaseName

声明jdbc/ApplicationContext_DatabaseName的各种属性和值在Tomcat的server.xml使用这样的事情:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContext_DatabaseName" auth="Container" type="javax.sql.DataSource"
              username="dbUsername" password="dbPasswd"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="5" maxWait="5000"
              maxActive="120" maxIdle="5"
              validationQuery="select 1"
              poolPreparedStatements="true"/>
</GlobalNamingResources/>

链接jdbc/ApplicationContext_DatabaseName从Web应用程序的性能META-INF/context.xml由应用程序私有的JNDI上下文java:comp/env/在指定的name属性:

<Context path="/ApplicationContext" ... >
  <!--
    "global" attribute links to GlobalNamingResources in the ${catalina.base}/conf/server.xml (server administrator team)
    "name" attribute is relative to the application-private JNDI context java:comp/env/ and is looked up from the java web application (application developer team)
  -->
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName" name="jdbc/DatabaseName" type="javax.sql.DataSource"/>
</Context>

最后,为了使用JNDI资源,指定的JNDI名称jdbc/DatabaseName在Web应用程序的部署描述符:

<resource-ref>
    <description>DatabaseName's Datasource</description>
    <res-ref-name>jdbc/DatabaseName</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref> 

在Spring上下文:

<jee:jndi-lookup id="DatabaseNameDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />

方法3周的缺点

如果JNDI名称得到改变,然后双方server.xmlMETA-INF/context.xml将被编辑和部署是必要的; 不过这种情况很少见。

方法3个变化

通过一个Web应用程序使用的许多数据源

只需添加配置到Tomcat的server.xml

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContext_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContext_DatabaseName2" ... />
  ...
</GlobalNamingResources/>

添加链接Web应用程序META-INF/context.xml由应用程序私有的JNDI上下文java:comp/env/在指定的name属性:

<Context path="/ApplicationContext" ... >
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
  ...
</Context>

最后加入Web应用程序的部署描述符JNDI资源的使用:

<resource-ref>
    <description>DatabaseName1's Datasource</description>
    <res-ref-name>jdbc/DatabaseName1</res-ref-name> ... 
</resource-ref> 
<resource-ref>
    <description>DatabaseName2's Datasource</description>
    <res-ref-name>jdbc/DatabaseName2</res-ref-name> ... 
</resource-ref>
...

在Spring上下文:

<jee:jndi-lookup id="DatabaseName1DataSource"
   jndi-name="jdbc/DatabaseName1" ... />
<jee:jndi-lookup id="DatabaseName2DataSource"
   jndi-name="jdbc/DatabaseName2" ... />
...


在同一台服务器上使用的许多Web应用程序许多数据源

只需添加配置到Tomcat的server.xml

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContextX_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContextX_DatabaseName2" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName2" ... />
  ...
</GlobalNamingResources/>

其他配置应该是从以前的变化的情况下可推论。


许多数据源到同一个数据库在同一台服务器上使用的许多Web应用程序

在这种情况下,一个Tomcat的server.xml的配置,如:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContextX_DatabaseName" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName" ... />

在两种不同的网络应用程序结束META-INF/context.xml ,如:

<Context path="/ApplicationContextX" ... >
  <ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>

和这样的:

<Context path="/ApplicationContextY" ... >
  <ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>

所以有人可能会担心的事实,同样的name="jdbc/DatabaseName"中查找,然后使用由部署在同一服务器上的两个不同的应用程序:这不是一个问题,因为jdbc/DatabaseName是应用程序-私人JNDI上下文java:comp/env/ ,所以ApplicationContextX 使用java:comp/env/不能够(设计)查找连接到资源global="jdbc/ApplicationContextY_DatabaseName"

当然,如果你没有这样的担心感到更放松,你可以使用像一个不同的命名策略:

<Context path="/ApplicationContextX" ... >
  <ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/applicationXprivateDatabaseName" ... />
</Context>

和这样的:

<Context path="/ApplicationContextY" ... >
  <ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/applicationYprivateDatabaseName" ... />
</Context>


Answer 2:

我宁愿方法2(把所有的东西(不仅在配置一些属性),

但不是将它们放置在全球server.xml或全球context.xml ,你应该将它放在专用context.xml.default YOUR_APP.xml在你的tomcat。

YOUR_APP.xml文件位于$catalinaHome/conf/<engine>/<host> (例如CONF /卡塔利娜/本地主机/ YOUR_APP.xml)。

在专用的配置YOUR_APP.xml仅适用于特定的应用。



Answer 3:

方法4

而不是使用JNDI的和我一起工作.properties文件和程序的初始化上,而不是配置时间内构建复杂的对象

你已经使用Spring,很容易构建DataSource的:

<context:property-placeholder location="classpath:app.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@${db.host}:${db.port}:${db.user}"/>
    <property name="username" value="${db.user}"/>
    <property name="password" value="${db.pass}"/>
</bean>

我完全同意与拉尔夫在使用部署描述符$CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xml ,而是JNDI我喜欢平淡键值的文件!

随着春天注入上述特性为豆田很简单:

@Value("${db.user}") String defaultSchema;

而不是JNDI的:

@Inject ApplicationContext context;
Enviroment env = context.getEnvironment();
String defaultSchema = env.getProperty("db.user");

还需要注意的是EL允许这种(默认值和深递归替换):

@Value('${db.user:testdb}') private String dbUserName;

<property name='username' value='${db.user.${env}}'/>

外部化.properties文件,我使用了现代的Tomcat 7 org.apache.catalina.loader.VirtualWebappLoader :

<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
        virtualClasspath="/srv/web/app/"/>

所以,你的DEVOPS填写virtualClasspath与当地外部完整路径是每个应用程序独立,并把当地app.properties到该目录。

也可以看看:

  • 添加目录到Tomcat的classpath
  • 我可以在每个应用程序在Tomcat中创建一个自定义的类路径
  • 从.war文件外化的Tomcat Web应用程序配置
  • 如何读取属性文件中的Tomcat Web应用我的背景之外
  • 配置Tomcat来使用属性文件来加载数据库连接信息
  • 外部化配置Tomcat


Answer 4:

您还可以使用JNDI URL支持不同的应用配置测试,集成测试,生产。

<Context>
...
<Resource auth="Container" factory="com.benasmussen.jndi.url.URLFactory" 
name="url/MyUrl" type="java.net.URL" url="file:///your/path/to/file"/>
...
</Context>

<jee:jndi-lookup id="myUrl" jndi-name="java:comp/env/url/MyUrl" expected-type="java.net.URL" />

退房GitHub的项目Tomcat的JNDI URL支持启用Tomcat服务器JNDI URL支持。



Answer 5:

步骤1:context.xml中

    <Context path="/projectname">
  <Resource auth="Container" 
            driverClassName="com.mysql.jdbc.Driver"
            logAbandoned="true" 
            maxActive="100" ``
            maxIdle="30" 
            maxWait="10000" 
            name="refname" 
            removeAbandoned="true" 
            removeAbandonedTimeout="60" 
            type="javax.sql.DataSource" 
            url="jdbc:mysql://localhost:8080/dbname" 
            username="root"
            password="root"/>
</Context>

第2步:web.xml中

<resource-ref>
        <description>DB Connection</description>
        <res-ref-name>refname</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

第3步:创建一个类来获取连接

Connection connection = null;        
            Context context = (Context) new InitialContext().lookup("java:comp/env");
            DataSource ds = (DataSource) context.lookup("refname");
            connection = ds.getConnection();

一切设置



文章来源: Should you set up database connection properties in server.xml or context.xml