Spring 2.x 中文

2,374 views
2,257 views

Published on

Published in: Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,374
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
49
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Spring 2.x 中文

  1. 1. x Spring Framework 2.0 - An Overview
  2. 2. 大綱  Spring Framework 簡介  Spring 2.x 新增功能  結語 2
  3. 3. Spring Framework的誕生  Spring之父 – R.Johnson  畢業於澳洲雪梨大學  擁有音樂學(Musicology)博士的學位  JSR-154(Servlet 2.4)規格委員  公開發表  2002年出版的專書「J2EE Design and Development」第 10章以架構描述及範例碼的形式發表。  2003年10月以開放原始碼形式釋出1.0版。  在TSS發表「Introduction to Spring Framework」文章後開 始受到Java社群重視。 3
  4. 4. Spring Framework架構概觀 4
  5. 5. Spring Framework 的理論基礎  為什麼要了解Spring的理論基礎?  幫助您正確評估是否採用Spring Framework  縮短學習時間  完全發揮Spring Framework 的威力  主要理論基礎  控制權倒置 (Inversion of Control)  依賴性注入 (Dependency Injection) 5
  6. 6. Template Method  核心概念  主流程寫在父類別  可變的部份挖空變成抽象方法 public abstract class HttpServlet … { … protected service(…) { .. if(..HTTP Get..) doGet(..); else if (..HTTP Post..) doPost(..); 主流程 .. } public abstract void doGet(..); public abstract void doPost(..); ? 可變邏輯 … } 6
  7. 7. Template Method與Hook Method HttpServlet template method Service() { if(isHttpGet()) hook doGet() else if(isHttpPost()) doPost() } hook method doGet() MyHttpServlet doPost() 7
  8. 8. 應用程式框架(Application Framework)  定義  可重用的半成品,客製化後,成為一個可用的系統  功能  提供共同領域的抽象化機制  節省開發時間  使得應用程式整體有一定的架構風格  在Template Method中,我們將主流程封裝在父類別中  內含主流程的父類別就是「框架」  透過繼承,重用主流程的子類就是「元件」,更換不同的子類別, 框架就能呈現不同的行為 8
  9. 9. Inversion Of Control (IoC) 9
  10. 10. 依賴性(Dependency)  當某類別繼承另一類別、實作另一介面或者叫用 到其它類別,我們就說此類別依賴 (depends-on) 另一個類別。 public class MySessionBean implements javax.ejb.SessionBean { private javax.ejb.SessionContext ctx; public void ejbCreate() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext ctx) { this.ctx = ctx; } …(略)… } 10
  11. 11. 依賴性對程式碼造成負面的影響  依賴性(Dependency)會對程式碼的可重用性會造 成負面影響  依賴性愈低,程式的可重用性愈高。  Liskov代換法則也可以看成是降低依賴性的手法  將Client與實作類別中間用介面隔開,去除了Client及 實作類別中間的依賴性 <<create>> public MovieLister () { movieFinder = new MovieFinderImpl(); } 11
  12. 12. 物件生成控制權的倒置 public MovieFinder create() { … return new MovieFinderImpl(); } MovieFinderFactory <<create>> 12
  13. 13. Dependency Injection IoC Container 13
  14. 14. 輕量級容器與IoC  輕量級容器實質上是「物件生成」的控制權的倒置  輕量級容器又稱為「IoC Container」  輕量級容器中所指IoC和傳統框架型重用中的IoC意 義不同:  框架重用的IoC是「主流程主控權」的倒置  而IoC Container的IoC是「物件生成主控權」的倒置  M.Fowler建議使用依賴注入(Dependency Injection) 來指稱「物件生成主控權」的倒置,以避免概念上 的混淆 14
  15. 15. 小結  Template Method  Application Framework  Inversion of Control  Dependency  Dependency Injection 15
  16. 16. 大綱  Spring Framework簡介  Spring 2.0新增功能  Bean容器與Bean設定檔  剖面導向程式設計 (AOP)  永續性支援  Message-Driven POJO  結語 16
  17. 17. Bean 容器運作模式 客戶端 Bean 容器 Bean 設定檔 POJO 17
  18. 18. Bean設定檔的基本結構  Spring的Bean設定由三個部份組成:  XML宣告區段  標頭宣告區段  Bean宣告區段  DTD宣告方式 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> … </beans> 18
  19. 19. (Spring 2.x) XML Schema的宣告方式 <? xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans“ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans- 2.0.xsd"> <bean id="…" class="…"> <property name="…" value="…"/> … </bean> 儘可能採用XML Schema形式的宣告 <bean id="…" class="…"> … </bean> … </beans> 19
  20. 20. 設定Bean屬性 class ProductViewer { private Product product; … public void setProduct(Product product) { this.product = product; } <bean id="productViewer" class="ProductViewer"> <property name="product"> } <ref bean="myProduct"/> </property> </bean> <bean id="myProduct" class="Product"> <property name="productId" value="10001"/> </bean> 20
  21. 21. Setter Injection (Spring 2.0) class ProductViewer { private Product product; … public void setProduct(Product product) { this.product = product; } <bean id="productViewer" class="ProductViewer"> <property name="product“ ref="myProduct“ /> } </bean> <bean id="myProduct" class="Product"> <property name="productId" value="10001"/> </bean> 21
  22. 22. (Spring 2.x) p-namespace的簡便語法 在標頭加上「xmlns:p=http://www.springframework.org/schema/p」 即可使用 p-namespace的簡便語法 <bean id="myProduct" class="Product"> <property name="productId“ value="10001"/> <property name=“myName" ref=“anotherBean"/> </bean> <bean id="myProduct" class="Product" p:productId="10001" p:myName-ref=“anotherBean" /> 22
  23. 23. 取得Bean實例 (Code) 單一設定檔 ApplicationContext context = new ClassPathXmlApplicationContext( “beans-config.xml” ); Product b = (Product) context.getBean(“productB”); 多設定檔 String[] beanConfigs = new String[]{"bean-config1.xml", "bean-config2.xml"}; ApplicationContext context = new ClassPathXmlApplicationContext( beanConfigs ); 23
  24. 24. 大綱  Spring Framework簡介  Spring 2.0新增功能  Bean容器與Bean設定檔  剖面導向程式設計 (AOP)  永續性支援  Message-Driven POJO  結語 24
  25. 25. 商務邏輯和橫切面邏輯混雜的問題  系統開發過程中往往必須考量許 多和主要業務流程無關的橫切面 考量(Cross-Cutting Concerns)  交易(Transaction)  安全性  例外處理  記錄檔  若沒有仔細切分,容易讓程式碼 中商務流程和系統考量交雜在一 起,造成程式難以維護 25
  26. 26. 將剖面(Aspect)單獨考量  基於重用(Reuse)的原則,可以將這些「橫切面」的處理 邏輯抽出來成為一個「Aspect」單獨開發  開發完成後再一次套用在所有具有此需求的商務流程 商務領域考量 橫切面考量 26
  27. 27. Pointcuts、Join Points與Advices Advices Join Points Pointcuts 27
  28. 28. 寫作Advice類別 public class LogBeforeAdvice { … public void before(JoinPoint jointPoint) { …(要插入的邏輯) } } 28
  29. 29. (Spring 2.0) AOP命名空間的宣告 <? xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/ spring-aop-2.0.xsd"> … </beans> 29
  30. 30. execution( modifiers-pattern? ret-type-pattern (Spring 2.0) AOP宣告 declaring-type-pattern? name-pattern(param-pattern) throws-pattern? ) <bean id="logBeforeAdvice" class="mypackage.LogBeforeAdvice"/> <bean id="product" class="mypackage.Product"/> <aop:config> <aop:aspect id="logging" ref="logBeforeAdvice"> <aop:before pointcut="execution (* mypackage.Product.*(..))" method="before"/> </aop:aspect> </aop:config> 30
  31. 31. (Spring 2.0) AOP Annotations <bean id="logBeforeAdvice" class="mypackage.LogBeforeAdvice"/> <bean id="product" class="mypackage.Product"/> <aop:aspectj-autoproxy/> 31
  32. 32. (Spring 2.0) 寫作Advice類別 @Aspect public class LogBeforeAdvice { … @Before("execution(* mypackage.Product.*(..))" ) public void before(JoinPoint jointPoint) { …(要插入的邏輯) } } 32
  33. 33. 大綱  Spring Framework簡介  Spring 2.0新增功能  Bean容器與Bean設定檔  剖面導向程式設計 (AOP)  永續性與交易支援  Message-Driven POJO  結語 33
  34. 34. (Spring 2.0) 使用tx標籤進行宣告式交易 Transaction Manager execution(* *.ProductDao.*(..)) <tx:advice> Transaction Attribute= Require Isolation Level= Default productDao execution( modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) 34 throws-pattern? )
  35. 35. 使用tx標籤進行宣告式交易 <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor pointcut="execution(* *.ProductDao.*(..))" advice-ref="txAdvice" /> </aop:config> 35
  36. 36. (Spring 2.0) 使用@Transactional進行宣告式交易 <tx:annotation-driven transaction-manager="txManager" /> // 直接標記在介面的實作成品上 public class ProductDaoJdbcImpl extends JdbcDaoSupport implements ProductDao { @Transactional(readOnly = true) public List getProducts(){ …(存取資料) } @Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT) public void save(Product product){ …(存取資料) } } 36
  37. 37. Hibernate與JPA 開發人員可以選擇只使用JPA以確 保最大的相容性,或者透過 Hibernate API實作更進階的功能, 甚至也可以將二者混合使用! Java Persistence API Hibernate API Hibernate Annotation (JPA) Hibernate Annotation (Hibernate) Hibernate EntityManager Hibernate XML 對映檔 Hibernate Core 37
  38. 38. Spring對Hibernate的封裝 HibernateTemplate hibernate.cfg.xml Configuration Criteria Query persist() save() update() SessionFactory Session saveOrUpdate() delete() Transaction 38 SessionFactoryBean
  39. 39. (Spring 2.0) 使用JPA Annotations @Entity @Table(name = "TB_PRODUCT") public class Product { @Id @GeneratedValue(strategy=GenerationType.TABLE) @Column(name = "id") private int productId; @Column(name = "name") TB_PRODUCT: private String name; 名稱 主鍵 型別 id Yes Integer @Column(name = "price") name No varchar private int price; price No Integer …(以上三個私有欄位的getter methods及setter methods)… } 39
  40. 40. Spring-Hibernate-DAO整合策略 相依性注入 SessionFactoryBean HibernateTemplate HibernateDaoSupport ProductDao ProductDaoHibernateImpl 實作(implements) 繼承(extends) 40
  41. 41. Spring-Hibernate整合 public class ProductDaoHibernateImpl extends HibernateDaoSupport implements ProductDao { public void save(Product product) { getHibernateTemplate().save(product); } public List getProducts() throws DataAccessException { return (List) getHibernateTemplate().execute( new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Criteria criteria = session.createCriteria(Product.class); criteria.addOrder(Order.asc("price")); return criteria.list(); } 41 }); }// end getProducts
  42. 42. SessionFactoryBean (Annotation) <bean id="sessionFactory" class="org.springframework.orm.hibernate3. annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="annotatedClasses"> <list> <value>Product</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=true </value> </property> </bean> 42
  43. 43. Spring-Hibernate整合 將SessionFactory注入ProductDaoHibernateImpl <bean id="productDao“ class="ProductDaoHibernateImpl"> <property name="sessionFactory" ref="sessionFactory" /> </bean> 注入 注入 ProductDaoHibernateImpl SessionFactoryBean DataSource 43
  44. 44. 大綱  Spring Framework簡介  Spring 2.0新增功能  Bean容器與Bean設定檔  剖面導向程式設計 (AOP)  永續性支援  Message-Driven POJO  結語 44
  45. 45. (Spring 2.0) Message-Driven POJO public class MyMessageDrivenPojo implements MessageListener { public void onMessage(Message message){ … // 處理所收到的處理訊息 } } 主程式 public static void main(String[] args) { DefaultMessageListenerContainer container = (DefaultMessageListenerContainer) context.getBean("listenerContainer"); container.start(); } 45
  46. 46. Message-Driven POJO (MDP) <bean id="myMDP" class="MyMessageDrivenPojo" /> <bean id="listenerContainer“ class="org.springframework.jms.listener. DefaultMessageListenerContainer"> <property name="concurrentConsumers" value="2" /> <property name="connectionFactory" ref="jmsFactory" /> <property name="destination" ref="destination" /> <property name="messageListener" ref="myMDP" /> </bean> 46
  47. 47. 加入交易支援 <bean id="txManager" class="org.springframework.jms.connection. JmsTransactionManager"> <property name="connectionFactory" ref="connectionFactory" /> </bean> <bean id="listenerContainer“ class="org.springframework.jms.listener. DefaultMessageListenerContainer"> <property name="concurrentConsumers" value="2" /> <property name="connectionFactory" ref="jmsFactory" /> <property name="destination" ref="destination" /> <property name="messageListener" ref="myMDP" /> <property name="transactionManager" ref=“txManager" /> </bean> 47
  48. 48. 結語  Spring 2.0 是一個全方位的應用程式框架,主要 功能包含了:  輕量級容器  實現依賴注入(Dependency Injection)及非侵入性(No intrusive)的框架  提供AOP(Aspect-oriented programming)機制  提供對持久層(Persistence)、交易(Transaction)的支援  提供MVC Web框架的實現  對於其它常用企業服務API提供一致的模型封裝 48
  49. 49. Backup 49
  50. 50. 小結: Spring Framework的設計理念  透過介面進行系統設計(Programming by interface)  以傳統Java物件為主 (POJO-based Programming)  非侵入性  一致的設定檔格式 50
  51. 51. 依賴注入的型式  三種型式  從setter方法注入資源的Setter Injection  從建構子(Constructor)注入的Constructor Injection  透過介面(Interface)注入的Interface injection  Spring Framework支援Setter Injection與 Constructor Injection  透過介面的相依性注入具有較強的侵入性,所以Spring 並未採用。 51
  52. 52. 黏合用程式碼(Glue Code) 黏合用程式碼」所在的類別會依賴IoC Container MovieServlet MovieService IoC Container 52
  53. 53. 去除Glue Code MovieServlet MovieService IoCManagerServlet IoC Container 53
  54. 54. AOP觀念與術語  Aspect  代表一個Cross-Cutting Concerns  由Pointcut與Advice二類的元件所組成  Advice是Aspect的「具體實作」  Join Points  Advice在切入商務流程的「點」稱之為Join Point  就實作面來說,就是Advice在應用程式中被執行的時間點  Spring只支援類別方法的Join Points  Spring不支援Field成員的Join Points,Spring設計人員認為支援 Field的Join Points會破壞物件的封裝性 54
  55. 55. AOP觀念與術語(2)  Pointcut  Pointcut用來定義一群Join Points  當呼叫的方法符合Pointcut表示式時,系統會自動將Advice與方法 縫合(Weaving) 55
  56. 56. Hibernate的宣告式交易 一般區域交易 <bean id="txManager" class="org.springframework.jdbc.datasource. DataSourceTransactionManager"> <property name="dataSource" ref="myDataSource" /> </bean> Hibernate宣告式交易 <bean id="txManager" class="org.springframework.orm.hibernate3. HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> 56
  57. 57. NamedParameterJdbcTemplate String sql = "INSERT INTO t_user (name,age) VALUES(:userName, :userAge)"; Map namedParameters = new HashMap(); namedParameters.put("userName", name); namedParameters.put("userAge", age); NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource); List rows = jdbcTemplate.queryForList(sql, namedParameters); 57
  58. 58. SimpleJdbcTemplate  JDK 5.0以上適用,支援泛型 String sql = "SELECT * FROM user WHERE id=?"; ParameterizedRowMapper<User> mapper = new ParameterizedRowMapper<User>() { public User mapRow(ResultSet rs, int rowNum) throws SQLException { … return user; } }; SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource); jdbcTemplate.queryForObject(sql, mapper, id); 58
  59. 59. MessageListenerAdapter  上面例子中的MyMessageDrivenPojo 仍然具有相依性  必須繼承javax.jms.MessageListener介面  MessageListenerAdapter  完全切除MDP與JMS的依賴關係  假設使用者自行定義了訊息的處理介面  將介面傳入Adapter做為建構子的參數 public interface MyMessageHandler { void processMessage(String message); } 不需要實作MessageListener! 實作 Public class MyMessageHandlerImpl implements MyMessageHandler { …} 59
  60. 60. MessageListenerAdapter – 設定檔 <bean id="messageListenerAdapter" class="org.springframework.jms.listener. adapter.MessageListenerAdapter"> <constructor-arg> <bean class="MyMessageHandlerImpl"/> </constructor-arg> <property name="defaultListenerMethod“ value="processMessage"/> </bean> <bean id="listenerContainer“ class="org.springframework.jms.listener. DefaultMessageListenerContainer"> <property name="concurrentConsumers" value="2" /> <property name="connectionFactory" ref="jmsFactory" /> <property name="destination" ref="destination" /> <property name="messageListener" ref="messageListenerAdapter " /> </bean> 60

×