Spring 的核心哲學是在不影響 Java 對象設計的前提下,將對象納入框架管理。這與 EJB 的侵入式設計(要求實現特定接口、遵循嚴格規範)及 Avalon 等輕量級容器(要求實現 Serviceable 等接口)形成鮮明對比。為實現這一目標,Spring 大量採用反射機制,實現動態、靈活的框架設計。
Spring 解決的首個問題是如何管理 Bean。IOC 思想要求 Bean 間不直接調用,而是採用被動協作方式,因此 Bean 管理成為核心。org.springframework.beans 包中的 BeanWrapper 是關鍵組件,它作為 Bean 的包裝器,統一處理屬性設置(含嵌套屬性)和方法調用。
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("salary", 50000f);
bwComp.setPropertyValue("managingDirector", jim);
// 通過嵌套路徑訪問屬性
Float salary = (Float) bwComp.getPropertyValue("managingDirector.salary");
雖然代碼看似繁瑣,但 Spring 由此獲得了統一管理 Bean 屬性的能力。
有了單個 Bean 包裝,還需管理多個 Bean。Spring 採用 BeanFactory 統一接口,屏蔽創建細節:
反射技術使 Spring 不再依賴傳統工廠方法模式,而是根據類名動態創建對象,僅保留這兩種基本模式,並通過統一的 getBean() 接口對外暴露。
JDBC 雖封裝了底層數據庫,但仍存在大量樣板代碼(獲取連接、異常處理、釋放資源)且異常僅拋出 SQLException,信息不完備。Spring 提供兩大解決方案:
MappingSqlQuery 等類將查詢映射為業務對象,子類只需實現 mapRow(ResultSet, int):
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); }
}
JdbcTemplate 使用回調接口 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 作為整體框架,定義了 Web 層與後端業務層的連接方式,延續 MVC 思想但耦合更鬆散。控制器通過依賴注入獲取業務接口,不依賴具體實現:
public class GoogleSearchController implements Controller {
private IGoogleSearchPort google;
public void setGoogle(IGoogleSearchPort google) { this.google = google; }
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
String query = request.getParameter("query");
GoogleSearchResult result = google.doGoogleSearch(...);
return new ModelAndView("googleResults", "result", result);
}
}
Spring 以非侵入式設計、反射驅動的靈活擴展、模板化的 JDBC 封裝以及鬆耦合的分層集成,構建了極具吸引力的企業級應用框架。