摘要:之旅簡化開發的使命簡化開發為了降低開發的復雜性,采取如下關鍵策略基于的輕量級和最小侵入性編程通過依賴注入和面向接口實現松耦合基于切面和慣例進行聲明式編程通過切面和模版減少樣式代碼依賴注入耦合性具有兩面性一方面,緊密耦合的代碼難以測試難以復
Spring之旅 簡化Java開發
Spring的使命:簡化Java開發
為了降低Java開發的復雜性,采取如下關鍵策略:
基于POJO的輕量級和最小侵入性編程
通過依賴注入和面向接口實現松耦合
基于切面和慣例進行聲明式編程
通過切面和模版減少樣式代碼
* 耦合性具有兩面性(two-headed beast).
一方面,緊密耦合的代碼難以測試、難以復用、難以理解,并且典型地表現“打地鼠”式的bug特性(修復一個bug,將會出現一個或者更多新的bug) 另一方面,一定程度的耦合又是必須的--完全沒有耦合的代碼什么也做不了
* 通過DI,對象的依賴關系將由系統中負責協調各對象的第三方租件在創建對象的時候進行設定。對象無需自行創建或管理它們依賴關系,依賴關系將被自動
注入到需要它們的對象當中去
* 依賴注入會將所依賴的關系自動交給目標對象,而不是讓對象自己去獲取依賴
構造器注入(constructor injection)
創建應用組件之間協作的行為通常稱為裝配(wiring)
SlayDragonQuestBraveKnightPrintStream如何裝配起來?
XML(knights.xml)和Java描述配置(KnightConfig)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 基于Java的配置 * * @Configuration注解表明這個類是一個配置類,該類應該包含在Spring應用上下文中如何創建bean的細節 */ @Configuration public class KnightConfig { @Bean public Knight knight(){ return new BraveKnight(quest()); } @Bean public Quest quest(){ return new SlayDragonQuest(System.out); } } import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; /** * 應用上下文容器的demo * */ public class ApplicationContextDemo { //在指定的文件系統中查找knight.xml文件 ApplicationContext context_1 = new FileSystemXmlApplicationContext("c:/knight.xml"); //從所有的類路徑下查找knight.xml文件 ApplicationContext context_2 = new ClassPathXmlApplicationContext("knight.xml"); //從Java配置中加載應用上下文 ApplicationContext context_3 = new AnnotationConfigApplicationContext(com.leaf.u_spring.chapter01.KnightConfig.class); }應用切面
DI能夠讓相互協作的軟件組織保持松耦合,而面向切面編程(aspect-oriented programming, AOP)允許你把遍布應用各處的功能分離出來形成可重用的組件
關注點是橫切面,如將安全、事務和日志關注點和核心業務邏輯相分離
使用模板消除樣板式代碼樣板式代碼(boilerplate code)
import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; /** * 樣板式代碼(boilerplate code) * 模擬JDBC操作 * */ public class BoilerplateCode { DataSource dataSource = null; String sql = "select id, firstname, lastname, salary from employee where id=?"; //改造前 public Employee getEmployeeById(long id){ Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = dataSource.getConnection(); //查找員工 stmt = conn.prepareStatement(sql); rs = stmt.executeQuery(); Employee employee = null; if(rs.next()){ //根據數據創建對象 employee = new Employee(); employee.setId(rs.getLong("id")); employee.setFirstName(rs.getString("firstname")); employee.setLastName(rs.getString("lastname")); employee.setSalary(rs.getBigDecimal("salary")); } return employee; } catch (SQLException e) { // 撲捉異常,也做不了太多事 } finally { if(rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return null; } private JdbcTemplate jdbcTemplate; //改造后 //模板能夠讓你的代碼關注于自身的職責 public Employee getEmployeeById_1(long id){ //SQL查詢 return jdbcTemplate.queryForObject(sql, new RowMapperSpring 容器(){ //將結果匹配為對象 @Override public Employee mapRow(ResultSet rs, int rowNum) throws SQLException { Employee employee = new Employee(); employee.setId(rs.getLong("id")); employee.setFirstName(rs.getString("firstname")); employee.setLastName(rs.getString("lastname")); employee.setSalary(rs.getBigDecimal("salary")); return employee; } //指定查詢參數 }, id); } } class Employee { private Long id; private String firstName; private String lastName; private BigDecimal salary; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public BigDecimal getSalary() { return salary; } public void setSalary(BigDecimal salary) { this.salary = salary; } }
在基于Spring的應用中,你的應用對象生存于Spring容器(container)中。
Spring容器負責創建對象,裝配它們,配置它們并管理它們的整個生命周期,從生存到死亡(new到finalize)
應用上下文,Spring容器的一種
AnnotationConfigApplicationContext:從一個或多個基于Java的配置類中加載Spring應用上下文
AnnotationConfigWebApplicationContext:從一個或多個基于Java的配置類中加載Spring Web應用上下文
ClassPathXmlApplicationContext:從類路徑下的一個或多個XML配置文件中加載上下文定義,把應用上下文的定義文件作為類資源
FileSystemXmlApplicationContext:從文件系統下的一個或多個XML配置文件中加載上下文定義
XmlWebApplicationContext:從Web應用下的一個或多個XML配置文件中加載上下文定義
bean的生命周期
Spring對bean進行實例化
Spring將值和bean的引用注入到bean對應的屬性中
如果bean實現了BeanNameAware接口,Spring將bean的ID傳遞給setBeanName()方法
如果bean實現了BeanFactoryAware接口,Spring將調用setBeanFactory()方法,將BeanFactory容器實例傳入
如果bean實現了ApplicationContextAware接口,Spring將調用setApplicationContext()方法,將bean所在的應用上下文的引用傳入進來
如果bean實現了BeanPostProcessor接口,Spring將調用它們的postProcessBeforeInitialization()方法
如果bean實現了InitializingBean接口,Spring將調用它們的afterPropertiesSet()方法。
類似地,如果bean使用了init-method聲明了初始化方法,該方法也會被調用
如果bean實現了BeanPostProcessor接口,Spring將調用它們的afterProcessBeforeInitialization()方法
此時,bean已經準備就緒,可以被應用程序使用了,它們將一直駐留在應用上下文中,直到該應用上下文被銷毀
如果bean實現了DisposableBean接口,Spring將調用它的destroy()接口方法。
同樣,如果bean使用destory-method聲明了銷毀方法,該方法也會被調用
在Spring4.0中,Spring框架的發布版包括了20個不同的模塊,每個模塊會有3個JAR文件(二進制類庫、源碼的JAR文件以及JavaDoc的JAR文件)
Spring核心容器,bean工廠、應用上下文等
Spring的AOP模塊,AOP、Aspects
數據訪問和集成,JDBC、Transaction、ORM、OXM、Messaging、JMS
WEB與遠程調用,WEB、WEB servlet、WEB portlet、WebSocket
Instrumentation,為Tomcat提供了一個織入代理,能夠為Tomcat傳遞類文件
Spring PortfolioSpring Web Flow ,為基于流程的會話式Web應用提供了支持
Spring Web Service
Spring Security,利用Spring AOP,Spring Security為Spring應用提供了聲明式的安全機制
Spring Integration,提供了多種通用應用集成模式的Spring聲明式風格實現
Spring Batch
Spring Data 支持關系型數據庫和非關系型數據庫
Spring Social 社交網絡擴展模塊
Spring Mobile移動應用
Spring for Android
Spring Boot大量依賴于自動配置技術
Spring 3.1新特性引入環境profile功能,解決各種環境(開發、測試、生產)選擇不通配置的問題
添加了多個enable注解,注解啟用Spring的特定功能
添加了Spring對聲明式緩存的支持,能夠使用簡單的注解聲明緩存邊界和規則
新添加的用于構造器注入的c命名空間
開始支持Servlet3.0,包括基于Java的配置中聲明Servlet和Filter
改善對JPA的支持
自動綁定路徑變量到模型屬性中
提供了@RequestMappingproduces和consumes屬性,用于匹配請求中的Accept和Content-Type頭部信息
提供了@RequestPart注解,用于將multipart請求中的某些部分綁定到處理器的方法參數中
支持flash屬性以及用于在請求間存放flash屬性的RedirectAttributes類型
Spring 3.2新特性可以使用Servlet3.0的異步請求
引入了Spring MVC測試框架
基于RestTemplate的客戶端的測試支持
@ControllerAdvice注解能夠將通用的@ExceptionHandler、@InitBinder和@ModelAttributes方法集中到一個類中,并應用到所有控制器上
支持完整的內容協商(full content negotiation)
@MatrixVariable注解能綁定矩陣變量到方法參數中
基礎的抽象類AbstractDispatcherServletInitializer能夠非常便利地配置DispatcherServlet
新增了ResponseEntityExceptionHandler
RestTemplate和@RequestBody的參數可以支持泛型
RestTemplate和@RequestMapping可以支持HTTP PATCH方法
在攔截器匹配時,支持使用URL模式將其排除在攔截器的處理功能之外
@Autowired @Value @Bean
@DateTimeFormat
提供了對JCache5.0的支持
支持定義全局來解析和渲染日期和時間
在集成測試中,能夠配置和加載WebApplicationContent
在集成測試中,能夠針對request和session作用域的bean進行測試
Spring 4.0 新特性支持WebSocket
提供高層次的面向消息的編程模型,基于SockJS
支持Java8特性
添加了條件化創建bean的功能
包含了Spring RestTemplate的一個新的異步實現
Spring 致力于簡化企業級Java開發,促進代碼的松散耦合
依賴注入和AOP是Spring框架最核心的部分
引用:《Spring In Action 4》第1章
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70887.html
摘要:基于上的我們還可以實現幾個基于的,還是老樣子,先讓我們創建兩個好了,現在我們想要實現兩個的,但是條件是通過的和的這樣我們也可以得到結果。 Merge, Join, Concat 大家好,我有回來啦,這周更新的有點慢,主要是因為我更新了個人簡歷哈哈,如果感興趣的朋友可以去看看哈: 我的主頁 個人認為還是很漂亮的~,不得不說,很多時候老外的設計能力還是很強。 好了,有點扯遠了,這一期我想和...
摘要:除了,還簡單介紹了對的支持,可以幫助應用將散落在各處的邏輯匯集于一處切面。當裝配的時候,這些切面能夠運行期編織起來,這樣就能呢個非常有效的賦予新功能。 第1章 Spring之旅 說明 1、本文參考了《Spring 實戰》重點內容,參考了GitHub上的代碼 2、每個人的學習方式不一樣,但目的是一樣的,活學活用。最近一直在聽《我們不一樣》 3、本文只為記錄作為以后參考,要想真正領悟Sp...
摘要:的版本增加了對事件監聽程序的支持,事件監聽程序在建立修改和刪除會話或環境時得到通知。元素指出事件監聽程序類。過濾器配置將一個名字與一個實現接口的類相關聯。 1.簡介 web.xml文件是Java web項目中的一個配置文件,主要用于配置歡迎頁、Filter、Listener、Servlet等,但并不是必須的,一個java web項目沒有web.xml文件照樣能跑起來。Tomcat容器/...
閱讀 1951·2021-09-07 09:59
閱讀 2520·2019-08-29 16:33
閱讀 3688·2019-08-29 16:18
閱讀 2849·2019-08-29 15:30
閱讀 1678·2019-08-29 13:52
閱讀 2035·2019-08-26 18:36
閱讀 530·2019-08-26 12:19
閱讀 694·2019-08-23 15:23