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