Tôi thích cách tiếp cận thứ ba tận dụng tốt nhất từ
Cách tiếp cận 1 và Cách tiếp cận 2 được mô tả bởi người dùng1016403 .
Phương pháp 3
- Lưu thuộc tính cơ sở dữ liệu trên
server.xml
- tham chiếu các
server.xml
thuộc tính cơ sở dữ liệu từ ứng dụng webMETA-INF/context.xml
Tiếp cận 3 lợi ích
Trong khi điểm đầu tiên hữu ích vì lý do bảo mật, điểm thứ hai hữu ích để tham chiếu giá trị thuộc tính máy chủ từ ứng dụng web, ngay cả khi giá trị thuộc tính máy chủ sẽ thay đổi.
Hơn nữa, việc tách các định nghĩa tài nguyên trên máy chủ khỏi việc sử dụng chúng bởi ứng dụng web làm cho cấu hình đó có thể mở rộng giữa các tổ chức với độ phức tạp khác nhau trong đó các nhóm khác nhau làm việc trên các tầng / lớp khác nhau: nhóm quản trị viên máy chủ có thể làm việc mà không xung đột với nhóm nhà phát triển nếu quản trị viên chia sẻ cùng Tên JNDI với nhà phát triển cho mỗi tài nguyên.
Phương pháp 3 thực hiện
Xác định tên JNDI jdbc/ApplicationContext_DatabaseName
.
Khai báo jdbc/ApplicationContext_DatabaseName
các thuộc tính và giá trị khác nhau của Tomcat server.xml
bằng cách sử dụng một cái gì đó như sau:
<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/>
Liên kết các jdbc/ApplicationContext_DatabaseName
thuộc tính của từ ứng dụng web META-INF/context.xml
bằng ngữ cảnh JNDI dành riêng cho ứng dụng java:comp/env/
được chỉ định trong name
thuộc tính:
<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>
Cuối cùng, để sử dụng tài nguyên JNDI, hãy chỉ định tên JNDI jdbc/DatabaseName
trong bộ mô tả triển khai của ứng dụng 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>
và trong bối cảnh mùa xuân:
<jee:jndi-lookup id="DatabaseNameDataSource"
jndi-name="jdbc/DatabaseName"
expected-type="javax.sql.DataSource" />
Tiếp cận 3 nhược điểm
Nếu tên JNDI bị thay đổi thì cả dấu server.xml
và ý META-INF/context.xml
muốn đều phải được chỉnh sửa và cần phải triển khai; tuy nhiên trường hợp này rất hiếm.
Tiếp cận 3 biến thể
Nhiều nguồn dữ liệu được sử dụng bởi một ứng dụng web
Chỉ cần thêm cấu hình vào Tomcat's server.xml
:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContext_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContext_DatabaseName2" ... />
...
</GlobalNamingResources/>
Thêm ứng dụng web liên kết META-INF/context.xml
theo ngữ cảnh JNDI dành riêng cho ứng dụng java:comp/env/
được chỉ định trong name
thuộc tính:
<Context path="/ApplicationContext" ... >
<ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
<ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
...
</Context>
Cuối cùng, thêm việc sử dụng tài nguyên JNDI trong bộ mô tả triển khai của ứng dụng web:
<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>
...
và trong bối cảnh mùa xuân:
<jee:jndi-lookup id="DatabaseName1DataSource"
jndi-name="jdbc/DatabaseName1" ... />
<jee:jndi-lookup id="DatabaseName2DataSource"
jndi-name="jdbc/DatabaseName2" ... />
...
Nhiều nguồn dữ liệu được sử dụng bởi nhiều ứng dụng web trên cùng một máy chủ
Chỉ cần thêm cấu hình vào Tomcat's server.xml
:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContextX_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContextX_DatabaseName2" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName1" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName2" ... />
...
</GlobalNamingResources/>
cấu hình khác phải được suy ra từ trường hợp biến thể trước đó.
Nhiều nguồn dữ liệu đến cùng một cơ sở dữ liệu được sử dụng bởi nhiều ứng dụng web trên cùng một máy chủ
Trong trường hợp này, server.xml
cấu hình của Tomcat như:
<GlobalNamingResources>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... />
<Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
kết thúc trong hai ứng dụng web khác nhau META-INF/context.xml
như:
<Context path="/ApplicationContextX" ... >
<ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>
và thích:
<Context path="/ApplicationContextY" ... >
<ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>
vì vậy ai đó có thể lo lắng về thực tế name="jdbc/DatabaseName"
là hai ứng dụng khác nhau được triển khai trên cùng một máy chủ tra cứu và sau đó sử dụng cùng một máy chủ: đây không phải là vấn đề vì đây jdbc/DatabaseName
là ngữ cảnh JNDI riêng tư của ứng dụng java:comp/env/
, vì vậy ApplicationContextX
bằng cách sử dụngjava:comp/env/
không thể (theo thiết kế) tra cứu tài nguyên được liên kết với global="jdbc/ApplicationContextY_DatabaseName"
.
Tất nhiên nếu bạn cảm thấy thoải mái hơn mà không phải lo lắng về điều này, bạn có thể sử dụng một chiến lược đặt tên khác như:
<Context path="/ApplicationContextX" ... >
<ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/applicationXprivateDatabaseName" ... />
</Context>
và thích:
<Context path="/ApplicationContextY" ... >
<ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/applicationYprivateDatabaseName" ... />
</Context>
<Resource name="jdbc/ApplicationContextX_DatabaseName" ... /> <Resource name="jdbc/ApplicationContextY_DatabaseName" ... />
Nếu các tài nguyên là nhóm kết nối, điều này có cung cấp cho bạn hai nhóm riêng biệt, mỗi nhóm một ứng dụng web không? Trong khi, nếu tôi liên kết từ cả hai ứng dụng web với một tài nguyên, sẽ chỉ có một nhóm kết nối, đúng không? Bất kỳ lý do nào để thích cái này hơn cái kia? (nhóm kết nối DB riêng biệt một nhóm cho mỗi ứng dụng web so với một nhóm kết nối được chia sẻ bởi tất cả các ứng dụng web)? Cảm ơn.