目前格式:HTML/XML
在 Spring 6、Java 17 與 Tomcat 10 的環境下,使用 JNDI 注入資料源時,最關鍵的衝突點在於 Jakarta EE 命名空間的轉換。
雖然 javax.sql.DataSource 是少數在 Jakarta 遷移中保持不變的類別(它屬於 Java SE 標準庫),但 Spring 6 內部的其他組件(如 JPA 或 Transaction Manager)已經全面轉向 Jakarta。
以下是針對你目前「連不上資料庫」且報出 NoSuchBeanDefinitionException 的完整對策:
1. 檢查 server.xml 的 Resource 配置
請確保你的配置包含 type="javax.sql.DataSource"。雖然是 Tomcat 10,但根據官方文件,此類型名稱通常仍維持 javax(除非特定實作要求)。
XML
<Resource name="jdbc/MyMSSQL"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://localhost:1433;databaseName=YourDB;encrypt=true;trustServerCertificate=true;"
username="sa"
password="your_password"
maxTotal="20" />
注意: 務必加上 encrypt=true;trustServerCertificate=true;,因為新版 MSSQL JDBC 驅動預設強制加密連線。
2. Spring 6 的 Java Config 寫法
在 Spring 6 中,為了讓 Spring 容器「看見」Tomcat 提供的 JNDI 資源,你必須定義一個 Bean 來進行查找。
Java
import javax.sql.DataSource; // 這裡用 javax 是正確的
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
// 如果你的 Resource Name 是 "jdbc/MyMSSQL"
// lookup 會自動處理 "java:comp/env/" 前綴
return lookup.getDataSource("jdbc/MyMSSQL");
}
}
3. 排查「找不到 Bean」的常見原因
如果你的代碼已經有類似上述配置但仍報錯,請檢查以下幾點:
JNDI 名稱不對稱:server.xml 的 name 必須與 lookup.getDataSource() 的字串完全一致(包含大小寫)。
缺少 web.xml 引用:在 Tomcat 中使用 JNDI,建議在 WEB-INF/web.xml 中宣告:
XML
<resource-ref>
<res-ref-name>jdbc/MyMSSQL</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
驅動程式位置:確認 mssql-jdbc-12.x.x.jre17.jar 是放在 Tomcat 的 lib/ 目錄 下,而不是專案的 WEB-INF/lib。這是因為 server.xml 是由 Tomcat 啟動載入的,它看不見你專案內部的 Jar。
4. 針對 Spring 6 的特別檢查
如果你使用的是 Spring Boot 3 (內含 Spring 6) 但佈署到外部 Tomcat: 你需要在 application.properties 中指定 JNDI 路徑,這樣 Spring Boot 的自動配置才會去抓:
Properties
spring.datasource.jndi-name=java:comp/env/jdbc/MyMSSQL
這段 MSSQL JDBC 連線範例 雖然是在展示基本的 JDBC 連線,但它對於確認你的 SQL Server 連線字串(包含新版驅動要求的 encrypt 參數)非常有幫助,這往往是 JNDI 配置中容易出錯的細節。
你的 server.xml 中 Resource 的 name 是設定為什麼?我可以幫你核對 Spring 端對應的 Lookup 字串。
5ZyoIFNwcmluZyA244CBSmF2YSAxNyDoiIcgVG9tY2F0IDEwIOeahOeSsOWig+S4i++8jOS9v+eUqCBKTkRJIOazqOWFpeizh+aWmea6kOaZgu+8jOacgOmXnOmNteeahOihneeqgem7nuWcqOaWvCBKYWthcnRhIEVFIOWRveWQjeepuumWk+eahOi9ieaPm+OAggoKCgrpm5bnhLYgamF2YXguc3FsLkRhdGFTb3VyY2Ug5piv5bCR5pW45ZyoIEpha2FydGEg6YG356e75Lit5L+d5oyB5LiN6K6K55qE6aGe5Yil77yI5a6D5bGs5pa8IEphdmEgU0Ug5qiZ5rqW5bqr77yJ77yM5L2GIFNwcmluZyA2IOWFp+mDqOeahOWFtuS7lue1hOS7tu+8iOWmgiBKUEEg5oiWIFRyYW5zYWN0aW9uIE1hbmFnZXLvvInlt7LntpPlhajpnaLovYnlkJEgSmFrYXJ0YeOAggoKCgrku6XkuIvmmK/ph53lsI3kvaDnm67liY3jgIzpgKPkuI3kuIros4fmlpnluqvjgI3kuJTloLHlh7ogTm9TdWNoQmVhbkRlZmluaXRpb25FeGNlcHRpb24g55qE5a6M5pW05bCN562W77yaCgoKCjEuIOaqouafpSBzZXJ2ZXIueG1sIOeahCBSZXNvdXJjZSDphY3nva4KCuiri+eiuuS/neS9oOeahOmFjee9ruWMheWQqyB0eXBlPSJqYXZheC5zcWwuRGF0YVNvdXJjZSLjgILpm5bnhLbmmK8gVG9tY2F0IDEw77yM5L2G5qC55pOa5a6Y5pa55paH5Lu277yM5q2k6aGe5Z6L5ZCN56ix6YCa5bi45LuN57at5oyBIGphdmF477yI6Zmk6Z2e54m55a6a5a+m5L2c6KaB5rGC77yJ44CCCgoKClhNTAoKCgo8UmVzb3VyY2UgbmFtZT0iamRiYy9NeU1TU1FMIgoKICAgICAgICAgIGF1dGg9IkNvbnRhaW5lciIKCiAgICAgICAgICB0eXBlPSJqYXZheC5zcWwuRGF0YVNvdXJjZSIKCiAgICAgICAgICBkcml2ZXJDbGFzc05hbWU9ImNvbS5taWNyb3NvZnQuc3Fsc2VydmVyLmpkYmMuU1FMU2VydmVyRHJpdmVyIgoKICAgICAgICAgIHVybD0iamRiYzpzcWxzZXJ2ZXI6Ly9sb2NhbGhvc3Q6MTQzMztkYXRhYmFzZU5hbWU9WW91ckRCO2VuY3J5cHQ9dHJ1ZTt0cnVzdFNlcnZlckNlcnRpZmljYXRlPXRydWU7IgoKICAgICAgICAgIHVzZXJuYW1lPSJzYSIKCiAgICAgICAgICBwYXNzd29yZD0ieW91cl9wYXNzd29yZCIKCiAgICAgICAgICBtYXhUb3RhbD0iMjAiIC8+Cgrms6jmhI/vvJog5YuZ5b+F5Yqg5LiKIGVuY3J5cHQ9dHJ1ZTt0cnVzdFNlcnZlckNlcnRpZmljYXRlPXRydWU777yM5Zug54K65paw54mIIE1TU1FMIEpEQkMg6amF5YuV6aCQ6Kit5by35Yi25Yqg5a+G6YCj57ea44CCCgoKCjIuIFNwcmluZyA2IOeahCBKYXZhIENvbmZpZyDlr6vms5UKCuWcqCBTcHJpbmcgNiDkuK3vvIzngrrkuoborpMgU3ByaW5nIOWuueWZqOOAjOeci+imi+OAjVRvbWNhdCDmj5DkvpvnmoQgSk5ESSDos4fmupDvvIzkvaDlv4XpoIjlrprnvqnkuIDlgIsgQmVhbiDkvobpgLLooYzmn6Xmib7jgIIKCgoKSmF2YQoKCgppbXBvcnQgamF2YXguc3FsLkRhdGFTb3VyY2U7IC8vIOmAmeijoeeUqCBqYXZheCDmmK/mraPnorrnmoQKCmltcG9ydCBvcmcuc3ByaW5nZnJhbWV3b3JrLmNvbnRleHQuYW5ub3RhdGlvbi5CZWFuOwoKaW1wb3J0IG9yZy5zcHJpbmdmcmFtZXdvcmsuY29udGV4dC5hbm5vdGF0aW9uLkNvbmZpZ3VyYXRpb247CgppbXBvcnQgb3JnLnNwcmluZ2ZyYW1ld29yay5qZGJjLmRhdGFzb3VyY2UubG9va3VwLkpuZGlEYXRhU291cmNlTG9va3VwOwoKCgpAQ29uZmlndXJhdGlvbgoKcHVibGljIGNsYXNzIERhdGFTb3VyY2VDb25maWcgewoKCgogICAgQEJlYW4KCiAgICBwdWJsaWMgRGF0YVNvdXJjZSBkYXRhU291cmNlKCkgewoKICAgICAgICBKbmRpRGF0YVNvdXJjZUxvb2t1cCBsb29rdXAgPSBuZXcgSm5kaURhdGFTb3VyY2VMb29rdXAoKTsKCiAgICAgICAgLy8g5aaC5p6c5L2g55qEIFJlc291cmNlIE5hbWUg5pivICJqZGJjL015TVNTUUwiCgogICAgICAgIC8vIGxvb2t1cCDmnIPoh6rli5XomZXnkIYgImphdmE6Y29tcC9lbnYvIiDliY3ntrQKCiAgICAgICAgcmV0dXJuIGxvb2t1cC5nZXREYXRhU291cmNlKCJqZGJjL015TVNTUUwiKTsKCiAgICB9Cgp9CgozLiDmjpLmn6XjgIzmib7kuI3liLAgQmVhbuOAjeeahOW4uOimi+WOn+WboAoK5aaC5p6c5L2g55qE5Luj56K85bey57aT5pyJ6aGe5Ly85LiK6L+w6YWN572u5L2G5LuN5aCx6Yyv77yM6KuL5qqi5p+l5Lul5LiL5bm+6bue77yaCgoKCkpOREkg5ZCN56ix5LiN5bCN56ix77yac2VydmVyLnhtbCDnmoQgbmFtZSDlv4XpoIjoiIcgbG9va3VwLmdldERhdGFTb3VyY2UoKSDnmoTlrZfkuLLlrozlhajkuIDoh7TvvIjljIXlkKvlpKflsI/lr6vvvInjgIIKCgoK57y65bCRIHdlYi54bWwg5byV55So77ya5ZyoIFRvbWNhdCDkuK3kvb/nlKggSk5ESe+8jOW7uuitsOWcqCBXRUItSU5GL3dlYi54bWwg5Lit5a6j5ZGK77yaCgoKClhNTAoKCgo8cmVzb3VyY2UtcmVmPgoKICAgIDxyZXMtcmVmLW5hbWU+amRiYy9NeU1TU1FMPC9yZXMtcmVmLW5hbWU+CgogICAgPHJlcy10eXBlPmphdmF4LnNxbC5EYXRhU291cmNlPC9yZXMtdHlwZT4KCiAgICA8cmVzLWF1dGg+Q29udGFpbmVyPC9yZXMtYXV0aD4KCjwvcmVzb3VyY2UtcmVmPgoK6amF5YuV56iL5byP5L2N572u77ya56K66KqNIG1zc3FsLWpkYmMtMTIueC54LmpyZTE3LmphciDmmK/mlL7lnKggVG9tY2F0IOeahCBsaWIvIOebrumMhCDkuIvvvIzogIzkuI3mmK/lsIjmoYjnmoQgV0VCLUlORi9saWLjgILpgJnmmK/lm6Dngrogc2VydmVyLnhtbCDmmK/nlLEgVG9tY2F0IOWVn+WLlei8ieWFpeeahO+8jOWug+eci+S4jeimi+S9oOWwiOahiOWFp+mDqOeahCBKYXLjgIIKCgoKNC4g6Yed5bCNIFNwcmluZyA2IOeahOeJueWIpeaqouafpQoK5aaC5p6c5L2g5L2/55So55qE5pivIFNwcmluZyBCb290IDMgKOWFp+WQqyBTcHJpbmcgNikg5L2G5L2I572y5Yiw5aSW6YOoIFRvbWNhdO+8miDkvaDpnIDopoHlnKggYXBwbGljYXRpb24ucHJvcGVydGllcyDkuK3mjIflrpogSk5ESSDot6/lvpHvvIzpgJnmqKMgU3ByaW5nIEJvb3Qg55qE6Ieq5YuV6YWN572u5omN5pyD5Y675oqT77yaCgoKClByb3BlcnRpZXMKCgoKc3ByaW5nLmRhdGFzb3VyY2Uuam5kaS1uYW1lPWphdmE6Y29tcC9lbnYvamRiYy9NeU1TU1FMCgrpgJnmrrUgTVNTUUwgSkRCQyDpgKPnt5rnr4Tkvosg6ZuW54S25piv5Zyo5bGV56S65Z+65pys55qEIEpEQkMg6YCj57ea77yM5L2G5a6D5bCN5pa856K66KqN5L2g55qEIFNRTCBTZXJ2ZXIg6YCj57ea5a2X5Liy77yI5YyF5ZCr5paw54mI6amF5YuV6KaB5rGC55qEIGVuY3J5cHQg5Y+D5pW477yJ6Z2e5bi45pyJ5bmr5Yqp77yM6YCZ5b6A5b6A5pivIEpOREkg6YWN572u5Lit5a655piT5Ye66Yyv55qE57Sw56+A44CCCgoKCuS9oOeahCBzZXJ2ZXIueG1sIOS4rSBSZXNvdXJjZSDnmoQgbmFtZSDmmK/oqK3lrprngrrku4DpurzvvJ/miJHlj6/ku6XluavkvaDmoLjlsI0gU3ByaW5nIOerr+WwjeaHieeahCBMb29rdXAg5a2X5Liy44CCCg==