Spring 的核心哲學是在不改變 Java 物件設計的前提下,將其納入框架管理。相較於 EJB 的侵入式設計(需實現特定介面)、Avalon 等輕量級容器的 Type 1 做法,Spring 採用反射與內省實現極致的靈活性與非侵入性。
org.springframework.beans.BeanWrapper 是 Spring 操作 Bean 屬性的統一入口。其默認實現 BeanWrapperImpl 透過反射完成屬性設值、取值、巢狀屬性存取與方法調用。
public class Company {
private String name;
private Employee managingDirector;
// getter/setter 略
}
public class Employee {
private float salary;
// getter/setter 略
}
Company c = new Company();
BeanWrapper bwComp = new BeanWrapperImpl(c);
bwComp.setPropertyValue("name", "Some Company Inc.");
Employee jim = new Employee();
BeanWrapper bwJim = new BeanWrapperImpl(jim);
bwJim.setPropertyValue("name", "Jim Stravinsky");
bwComp.setPropertyValue("managingDirector", jim);
// 透過巢狀路徑取值
Float salary = (Float) bwComp.getPropertyValue("managingDirector.salary");
雖代碼量增加,但 Spring 獲得了統一管理任意 Bean 屬性的能力,為 IOC 奠基。
Spring 以 BeanFactory 統一管理 Bean 實例,支援兩種模式:
反射技術使 Spring 不需像傳統工廠模式那樣為每個類編寫工廠方法,僅需根據類名動態實例化。BeanFactory.getBean() 統一入口屏蔽了實例化細節。
SQLException 無法表達具體錯誤類型JdbcTemplate 封裝固定流程,子類實現 mapRow() 映射結果集。
class UserQuery extends MappingSqlQuery {
public UserQuery(DataSource ds) {
super(ds, "SELECT * FROM PUB_USER_ADDRESS WHERE USER_ID = ?");
declareParameter(new SqlParameter(Types.NUMERIC));
compile();
}
protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(rs.getLong("USER_ID"));
user.setForename(rs.getString("FORENAME"));
return user;
}
public User findUser(long id) { return (User) findObject(id); }
}
RowCallbackHandler 處理每行數據,異常由模板統一捕獲轉換。
JdbcTemplate template = new JdbcTemplate(dataSource);
final List names = new LinkedList();
template.query("SELECT USER.NAME FROM USER",
new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
names.add(rs.getString(1));
}
});
Spring 定義了 Controller 介面,Web 層僅依賴業務介面(如 IGoogleSearchPort),透過 Setter 注入實現依賴倒置,不綁定具體實現技術(EJB、Web Service、本地 Bean 皆可)。
public class GoogleSearchController implements Controller {
private IGoogleSearchPort google;
private String googleKey;
public void setGoogle(IGoogleSearchPort google) { this.google = google; }
public void setGoogleKey(String googleKey) { this.googleKey = googleKey; }
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) {
String query = req.getParameter("query");
GoogleSearchResult result = google.doGoogleSearch(googleKey, query, ...);
return new ModelAndView("googleResults", "result", result);
}
}
Spring 透過反射、模板方法、回調與依賴注入,構建了非侵入、高內聚、低耦合的企業級開發框架,其核心思想貫穿於 Bean 管理、資料訪問、Web 層整合等各層面。