摘要:之旅簡(jiǎn)化開發(fā)的使命簡(jiǎn)化開發(fā)為了降低開發(fā)的復(fù)雜性,采取如下關(guān)鍵策略基于的輕量級(jí)和最小侵入性編程通過(guò)依賴注入和面向接口實(shí)現(xiàn)松耦合基于切面和慣例進(jìn)行聲明式編程通過(guò)切面和模版減少樣式代碼依賴注入耦合性具有兩面性一方面,緊密耦合的代碼難以測(cè)試難以復(fù)
Spring之旅 簡(jiǎn)化Java開發(fā)
Spring的使命:簡(jiǎn)化Java開發(fā)
為了降低Java開發(fā)的復(fù)雜性,采取如下關(guān)鍵策略:
基于POJO的輕量級(jí)和最小侵入性編程
通過(guò)依賴注入和面向接口實(shí)現(xiàn)松耦合
基于切面和慣例進(jìn)行聲明式編程
通過(guò)切面和模版減少樣式代碼
* 耦合性具有兩面性(two-headed beast).
一方面,緊密耦合的代碼難以測(cè)試、難以復(fù)用、難以理解,并且典型地表現(xiàn)“打地鼠”式的bug特性(修復(fù)一個(gè)bug,將會(huì)出現(xiàn)一個(gè)或者更多新的bug) 另一方面,一定程度的耦合又是必須的--完全沒有耦合的代碼什么也做不了
* 通過(guò)DI,對(duì)象的依賴關(guān)系將由系統(tǒng)中負(fù)責(zé)協(xié)調(diào)各對(duì)象的第三方租件在創(chuàng)建對(duì)象的時(shí)候進(jìn)行設(shè)定。對(duì)象無(wú)需自行創(chuàng)建或管理它們依賴關(guān)系,依賴關(guān)系將被自動(dòng)
注入到需要它們的對(duì)象當(dāng)中去
* 依賴注入會(huì)將所依賴的關(guān)系自動(dòng)交給目標(biāo)對(duì)象,而不是讓對(duì)象自己去獲取依賴
構(gòu)造器注入(constructor injection)
創(chuàng)建應(yīng)用組件之間協(xié)作的行為通常稱為裝配(wiring)
SlayDragonQuestBraveKnightPrintStream如何裝配起來(lái)?
XML(knights.xml)和Java描述配置(KnightConfig)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 基于Java的配置 * * @Configuration注解表明這個(gè)類是一個(gè)配置類,該類應(yīng)該包含在Spring應(yīng)用上下文中如何創(chuàng)建bean的細(xì)節(jié) */ @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; /** * 應(yīng)用上下文容器的demo * */ public class ApplicationContextDemo { //在指定的文件系統(tǒng)中查找knight.xml文件 ApplicationContext context_1 = new FileSystemXmlApplicationContext("c:/knight.xml"); //從所有的類路徑下查找knight.xml文件 ApplicationContext context_2 = new ClassPathXmlApplicationContext("knight.xml"); //從Java配置中加載應(yīng)用上下文 ApplicationContext context_3 = new AnnotationConfigApplicationContext(com.leaf.u_spring.chapter01.KnightConfig.class); }應(yīng)用切面
DI能夠讓相互協(xié)作的軟件組織保持松耦合,而面向切面編程(aspect-oriented programming, AOP)允許你把遍布應(yīng)用各處的功能分離出來(lái)形成可重用的組件
關(guān)注點(diǎn)是橫切面,如將安全、事務(wù)和日志關(guān)注點(diǎn)和核心業(yè)務(wù)邏輯相分離
使用模板消除樣板式代碼樣板式代碼(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()){ //根據(jù)數(shù)據(jù)創(chuàng)建對(duì)象 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; //改造后 //模板能夠讓你的代碼關(guān)注于自身的職責(zé) public Employee getEmployeeById_1(long id){ //SQL查詢 return jdbcTemplate.queryForObject(sql, new RowMapperSpring 容器(){ //將結(jié)果匹配為對(duì)象 @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; } //指定查詢參數(shù) }, 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的應(yīng)用中,你的應(yīng)用對(duì)象生存于Spring容器(container)中。
Spring容器負(fù)責(zé)創(chuàng)建對(duì)象,裝配它們,配置它們并管理它們的整個(gè)生命周期,從生存到死亡(new到finalize)
應(yīng)用上下文,Spring容器的一種
AnnotationConfigApplicationContext:從一個(gè)或多個(gè)基于Java的配置類中加載Spring應(yīng)用上下文
AnnotationConfigWebApplicationContext:從一個(gè)或多個(gè)基于Java的配置類中加載Spring Web應(yīng)用上下文
ClassPathXmlApplicationContext:從類路徑下的一個(gè)或多個(gè)XML配置文件中加載上下文定義,把應(yīng)用上下文的定義文件作為類資源
FileSystemXmlApplicationContext:從文件系統(tǒng)下的一個(gè)或多個(gè)XML配置文件中加載上下文定義
XmlWebApplicationContext:從Web應(yīng)用下的一個(gè)或多個(gè)XML配置文件中加載上下文定義
bean的生命周期
Spring對(duì)bean進(jìn)行實(shí)例化
Spring將值和bean的引用注入到bean對(duì)應(yīng)的屬性中
如果bean實(shí)現(xiàn)了BeanNameAware接口,Spring將bean的ID傳遞給setBeanName()方法
如果bean實(shí)現(xiàn)了BeanFactoryAware接口,Spring將調(diào)用setBeanFactory()方法,將BeanFactory容器實(shí)例傳入
如果bean實(shí)現(xiàn)了ApplicationContextAware接口,Spring將調(diào)用setApplicationContext()方法,將bean所在的應(yīng)用上下文的引用傳入進(jìn)來(lái)
如果bean實(shí)現(xiàn)了BeanPostProcessor接口,Spring將調(diào)用它們的postProcessBeforeInitialization()方法
如果bean實(shí)現(xiàn)了InitializingBean接口,Spring將調(diào)用它們的afterPropertiesSet()方法。
類似地,如果bean使用了init-method聲明了初始化方法,該方法也會(huì)被調(diào)用
如果bean實(shí)現(xiàn)了BeanPostProcessor接口,Spring將調(diào)用它們的afterProcessBeforeInitialization()方法
此時(shí),bean已經(jīng)準(zhǔn)備就緒,可以被應(yīng)用程序使用了,它們將一直駐留在應(yīng)用上下文中,直到該應(yīng)用上下文被銷毀
如果bean實(shí)現(xiàn)了DisposableBean接口,Spring將調(diào)用它的destroy()接口方法。
同樣,如果bean使用destory-method聲明了銷毀方法,該方法也會(huì)被調(diào)用
在Spring4.0中,Spring框架的發(fā)布版包括了20個(gè)不同的模塊,每個(gè)模塊會(huì)有3個(gè)JAR文件(二進(jìn)制類庫(kù)、源碼的JAR文件以及JavaDoc的JAR文件)
Spring核心容器,bean工廠、應(yīng)用上下文等
Spring的AOP模塊,AOP、Aspects
數(shù)據(jù)訪問(wèn)和集成,JDBC、Transaction、ORM、OXM、Messaging、JMS
WEB與遠(yuǎn)程調(diào)用,WEB、WEB servlet、WEB portlet、WebSocket
Instrumentation,為Tomcat提供了一個(gè)織入代理,能夠?yàn)門omcat傳遞類文件
Spring PortfolioSpring Web Flow ,為基于流程的會(huì)話式Web應(yīng)用提供了支持
Spring Web Service
Spring Security,利用Spring AOP,Spring Security為Spring應(yīng)用提供了聲明式的安全機(jī)制
Spring Integration,提供了多種通用應(yīng)用集成模式的Spring聲明式風(fēng)格實(shí)現(xiàn)
Spring Batch
Spring Data 支持關(guān)系型數(shù)據(jù)庫(kù)和非關(guān)系型數(shù)據(jù)庫(kù)
Spring Social 社交網(wǎng)絡(luò)擴(kuò)展模塊
Spring Mobile移動(dòng)應(yīng)用
Spring for Android
Spring Boot大量依賴于自動(dòng)配置技術(shù)
Spring 3.1新特性引入環(huán)境profile功能,解決各種環(huán)境(開發(fā)、測(cè)試、生產(chǎn))選擇不通配置的問(wèn)題
添加了多個(gè)enable注解,注解啟用Spring的特定功能
添加了Spring對(duì)聲明式緩存的支持,能夠使用簡(jiǎn)單的注解聲明緩存邊界和規(guī)則
新添加的用于構(gòu)造器注入的c命名空間
開始支持Servlet3.0,包括基于Java的配置中聲明Servlet和Filter
改善對(duì)JPA的支持
自動(dòng)綁定路徑變量到模型屬性中
提供了@RequestMappingproduces和consumes屬性,用于匹配請(qǐng)求中的Accept和Content-Type頭部信息
提供了@RequestPart注解,用于將multipart請(qǐng)求中的某些部分綁定到處理器的方法參數(shù)中
支持flash屬性以及用于在請(qǐng)求間存放flash屬性的RedirectAttributes類型
Spring 3.2新特性可以使用Servlet3.0的異步請(qǐng)求
引入了Spring MVC測(cè)試框架
基于RestTemplate的客戶端的測(cè)試支持
@ControllerAdvice注解能夠?qū)⑼ㄓ玫腀ExceptionHandler、@InitBinder和@ModelAttributes方法集中到一個(gè)類中,并應(yīng)用到所有控制器上
支持完整的內(nèi)容協(xié)商(full content negotiation)
@MatrixVariable注解能綁定矩陣變量到方法參數(shù)中
基礎(chǔ)的抽象類AbstractDispatcherServletInitializer能夠非常便利地配置DispatcherServlet
新增了ResponseEntityExceptionHandler
RestTemplate和@RequestBody的參數(shù)可以支持泛型
RestTemplate和@RequestMapping可以支持HTTP PATCH方法
在攔截器匹配時(shí),支持使用URL模式將其排除在攔截器的處理功能之外
@Autowired @Value @Bean
@DateTimeFormat
提供了對(duì)JCache5.0的支持
支持定義全局來(lái)解析和渲染日期和時(shí)間
在集成測(cè)試中,能夠配置和加載WebApplicationContent
在集成測(cè)試中,能夠針對(duì)request和session作用域的bean進(jìn)行測(cè)試
Spring 4.0 新特性支持WebSocket
提供高層次的面向消息的編程模型,基于SockJS
支持Java8特性
添加了條件化創(chuàng)建bean的功能
包含了Spring RestTemplate的一個(gè)新的異步實(shí)現(xiàn)
Spring 致力于簡(jiǎn)化企業(yè)級(jí)Java開發(fā),促進(jìn)代碼的松散耦合
依賴注入和AOP是Spring框架最核心的部分
引用:《Spring In Action 4》第1章
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70887.html
摘要:新特性重要功能升級(jí)為了解決各種環(huán)境下如開發(fā)測(cè)試和生產(chǎn)選擇不同配置的問(wèn)題,引入了環(huán)境功能。這個(gè)消息模塊支持的功能,同時(shí)提供了基于模板的方式發(fā)布消息是第一批支持特性的框架,比如它所支持的表達(dá)式。 Spring 3.1新特性 重要功能升級(jí) 為了解決各種環(huán)境下(如開發(fā)、測(cè)試和生產(chǎn))選擇不同配置的問(wèn)題,Spring 3.1引入了環(huán)境profile功能。借助于profile,就能根據(jù)應(yīng)用部署在什...
摘要:基于上的我們還可以實(shí)現(xiàn)幾個(gè)基于的,還是老樣子,先讓我們創(chuàng)建兩個(gè)好了,現(xiàn)在我們想要實(shí)現(xiàn)兩個(gè)的,但是條件是通過(guò)的和的這樣我們也可以得到結(jié)果。 Merge, Join, Concat 大家好,我有回來(lái)啦,這周更新的有點(diǎn)慢,主要是因?yàn)槲腋铝藗€(gè)人簡(jiǎn)歷哈哈,如果感興趣的朋友可以去看看哈: 我的主頁(yè) 個(gè)人認(rèn)為還是很漂亮的~,不得不說(shuō),很多時(shí)候老外的設(shè)計(jì)能力還是很強(qiáng)。 好了,有點(diǎn)扯遠(yuǎn)了,這一期我想和...
摘要:除了,還簡(jiǎn)單介紹了對(duì)的支持,可以幫助應(yīng)用將散落在各處的邏輯匯集于一處切面。當(dāng)裝配的時(shí)候,這些切面能夠運(yùn)行期編織起來(lái),這樣就能呢個(gè)非常有效的賦予新功能。 第1章 Spring之旅 說(shuō)明 1、本文參考了《Spring 實(shí)戰(zhàn)》重點(diǎn)內(nèi)容,參考了GitHub上的代碼 2、每個(gè)人的學(xué)習(xí)方式不一樣,但目的是一樣的,活學(xué)活用。最近一直在聽《我們不一樣》 3、本文只為記錄作為以后參考,要想真正領(lǐng)悟Sp...
摘要:的版本增加了對(duì)事件監(jiān)聽程序的支持,事件監(jiān)聽程序在建立修改和刪除會(huì)話或環(huán)境時(shí)得到通知。元素指出事件監(jiān)聽程序類。過(guò)濾器配置將一個(gè)名字與一個(gè)實(shí)現(xiàn)接口的類相關(guān)聯(lián)。 1.簡(jiǎn)介 web.xml文件是Java web項(xiàng)目中的一個(gè)配置文件,主要用于配置歡迎頁(yè)、Filter、Listener、Servlet等,但并不是必須的,一個(gè)java web項(xiàng)目沒有web.xml文件照樣能跑起來(lái)。Tomcat容器/...
閱讀 1968·2021-09-07 09:59
閱讀 2529·2019-08-29 16:33
閱讀 3709·2019-08-29 16:18
閱讀 2860·2019-08-29 15:30
閱讀 1689·2019-08-29 13:52
閱讀 2054·2019-08-26 18:36
閱讀 547·2019-08-26 12:19
閱讀 712·2019-08-23 15:23