Spring 透過 IOC(控制反轉) 與 DI(依賴注入) 實現元件解耦:
@Component、XML <bean> 定義優勢:單元測試容易、模組可替換、生命週期統一管理。
| 註解 | 層級 | 說明 |
|---|---|---|
@Controller | 控制層 | 接收 HTTP 請求,回傳視圖名或 JSON |
@RestController | 控制層 | @Controller + @ResponseBody,直接回傳資料 |
@Service | 業務層 | 封裝業務邏輯,交易管理邊界 |
@Repository | 資料存取層 | DAO 元件,自動轉換 JDBC 例外為 Spring DataAccessException |
@Component | 通用 | 泛型元件標記,掃描自動註冊 |
@RequestMapping | 方法/類 | URL 映射,支援 method、params、headers、consumes、produces |
@GetMapping 等 | 方法 | HTTP 動詞速寫註解 |
@Autowired | 欄位/建構子 | ByType 自動裝配,required=false 允許為 null |
@Resource | 欄位/Setter | JSR-250,預設 ByName,指定 name 時精確匹配 |
@Qualifier | 配合 @Autowired | 多實現時指定 Bean 名稱 |
@ResponseBody | 方法 | 回傳值直接寫入 HTTP Response Body(JSON/XML) |
@Transactional | 方法/類 | 宣告式交易,rollbackFor 指定回滾例外 |
@RequestMapping 方法Model/ModelAndView<!-- web.xml 註冊 DispatcherServlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- spring-mvc.xml 核心配置 -->
<context:component-scan base-package="com.example" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 靜態資源處理 -->
<mvc:resources mapping="/static/**" location="/static/" />
@ControllerAdvice + @ExceptionHandler 統一回傳錯誤碼/訊息HandlerInterceptor,配置 mvc:interceptors 做登入驗證、日誌、限流MultipartFile + CommonsMultipartResolver 或 StandardServletMultipartResolver❌
@Transactional加在 private 方法不生效 → 必須 public❌ 同類內部方法互相呼叫
@Transactional失效 → 需注入自己或用 AspectJ❌
@Autowired預設 required=true,找不到 Bean 啟動報錯 → 介面多實現時加@Qualifier