成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

談?wù)凷pring中都用到了哪些設(shè)計(jì)模式

新聞 架構(gòu)
JDK 中用到了那些設(shè)計(jì)模式?Spring 中用到了那些設(shè)計(jì)模式?這兩個(gè)問(wèn)題,在面試中比較常見(jiàn)。我在網(wǎng)上搜索了一下關(guān)于 Spring 中設(shè)計(jì)模式的講解幾乎都是千篇一律,而且大部分都年代久遠(yuǎn)。

 JDK 中用到了那些設(shè)計(jì)模式?Spring 中用到了那些設(shè)計(jì)模式?這兩個(gè)問(wèn)題,在面試中比較常見(jiàn)。我在網(wǎng)上搜索了一下關(guān)于 Spring 中設(shè)計(jì)模式的講解幾乎都是千篇一律,而且大部分都年代久遠(yuǎn)。所以,花了幾天時(shí)間自己總結(jié)了一下,由于我的個(gè)人能力有限,文中如有任何錯(cuò)誤各位都可以指出。另外,文章篇幅有限,對(duì)于設(shè)計(jì)模式以及一些源碼的解讀我只是一筆帶過(guò),這篇文章的主要目的是回顧一下 Spring 中的設(shè)計(jì)模式。

Design Patterns(設(shè)計(jì)模式) 表示面向?qū)ο筌浖_發(fā)中最好的計(jì)算機(jī)編程實(shí)踐。 Spring 框架中廣泛使用了不同類型的設(shè)計(jì)模式,下面我們來(lái)看看到底有哪些設(shè)計(jì)模式?

控制反轉(zhuǎn)(IoC)和依賴注入(DI)

IoC(Inversion of Control,控制翻轉(zhuǎn)) 是Spring 中一個(gè)非常非常重要的概念,它不是什么技術(shù),而是一種解耦的設(shè)計(jì)思想。它的主要目的是借助于“第三方”(Spring 中的 IOC 容器) 實(shí)現(xiàn)具有依賴關(guān)系的對(duì)象之間的解耦(IOC容易管理對(duì)象,你只管使用即可),從而降低代碼之間的耦合度。IOC 是一個(gè)原則,而不是一個(gè)模式,以下模式(但不限于)實(shí)現(xiàn)了IoC原則。

面試官:談?wù)凷pring中都用到了那些設(shè)計(jì)模式?

Spring IOC 容器就像是一個(gè)工廠一樣,當(dāng)我們需要?jiǎng)?chuàng)建一個(gè)對(duì)象的時(shí)候,只需要配置好配置文件/注解即可,完全不用考慮對(duì)象是如何被創(chuàng)建出來(lái)的。 IOC 容器負(fù)責(zé)創(chuàng)建對(duì)象,將對(duì)象連接在一起,配置這些對(duì)象,并從創(chuàng)建中處理這些對(duì)象的整個(gè)生命周期,直到它們被完全銷毀。

在實(shí)際項(xiàng)目中一個(gè) Service 類如果有幾百甚至上千個(gè)類作為它的底層,我們需要實(shí)例化這個(gè) Service,你可能要每次都要搞清這個(gè) Service 所有底層類的構(gòu)造函數(shù),這可能會(huì)把人逼瘋。如果利用 IOC 的話,你只需要配置好,然后在需要的地方引用就行了,這大大增加了項(xiàng)目的可維護(hù)性且降低了開發(fā)難度。關(guān)于Spring IOC 的理解,推薦看這一下知乎的一個(gè)回答:www.zhihu.com/question/23… ,非常不錯(cuò)。

控制翻轉(zhuǎn)怎么理解呢? 舉個(gè)例子:"對(duì)象a 依賴了對(duì)象 b,當(dāng)對(duì)象 a 需要使用 對(duì)象 b的時(shí)候必須自己去創(chuàng)建。但是當(dāng)系統(tǒng)引入了 IOC 容器后, 對(duì)象a 和對(duì)象 b 之前就失去了直接的聯(lián)系。這個(gè)時(shí)候,當(dāng)對(duì)象 a 需要使用 對(duì)象 b的時(shí)候, 我們可以指定 IOC 容器去創(chuàng)建一個(gè)對(duì)象b注入到對(duì)象 a 中"。 對(duì)象 a 獲得依賴對(duì)象 b 的過(guò)程,由主動(dòng)行為變?yōu)榱吮粍?dòng)行為,控制權(quán)翻轉(zhuǎn),這就是控制反轉(zhuǎn)名字的由來(lái)。

DI(Dependecy Inject,依賴注入)是實(shí)現(xiàn)控制反轉(zhuǎn)的一種設(shè)計(jì)模式,依賴注入就是將實(shí)例變量傳入到一個(gè)對(duì)象中去。

工廠設(shè)計(jì)模式

Spring使用工廠模式可以通過(guò) BeanFactory 或 ApplicationContext 創(chuàng)建 bean 對(duì)象。

兩者對(duì)比:

  • BeanFactory :延遲注入(使用到某個(gè) bean 的時(shí)候才會(huì)注入),相比于BeanFactory 來(lái)說(shuō)會(huì)占用更少的內(nèi)存,程序啟動(dòng)速度更快。
  • ApplicationContext :容器啟動(dòng)的時(shí)候,不管你用沒(méi)用到,一次性創(chuàng)建所有 bean 。BeanFactory 僅提供了最基本的依賴注入支持,ApplicationContext 擴(kuò)展了 BeanFactory ,除了有BeanFactory的功能還有額外更多功能,所以一般開發(fā)人員使用ApplicationContext會(huì)更多。

ApplicationContext的三個(gè)實(shí)現(xiàn)類:

  1. ClassPathXmlApplication:把上下文文件當(dāng)成類路徑資源。
  2. FileSystemXmlApplication:從文件系統(tǒng)中的 XML 文件載入上下文定義信息。
  3. XmlWebApplicationContext:從Web系統(tǒng)中的XML文件載入上下文定義信息。

Example:

  1. import org.springframework.context.ApplicationContext; 
  2. import org.springframework.context.support.FileSystemXmlApplicationContext; 
  3.   
  4. public class App { 
  5.     public static void main(String[] args) { 
  6.         ApplicationContext context = new FileSystemXmlApplicationContext( 
  7.                 "C:/work/IOC Containers/springframework.applicationcontext/src/main/resources/bean-factory-config.xml"); 
  8.   
  9.         HelloApplicationContext obj = (HelloApplicationContext) context.getBean("helloApplicationContext"); 
  10.         obj.getMsg(); 
  11.     } 
  12. 復(fù)制代碼 

單例設(shè)計(jì)模式

在我們的系統(tǒng)中,有一些對(duì)象其實(shí)我們只需要一個(gè),比如說(shuō):線程池、緩存、對(duì)話框、注冊(cè)表、日志對(duì)象、充當(dāng)打印機(jī)、顯卡等設(shè)備驅(qū)動(dòng)程序的對(duì)象。事實(shí)上,這一類對(duì)象只能有一個(gè)實(shí)例,如果制造出多個(gè)實(shí)例就可能會(huì)導(dǎo)致一些問(wèn)題的產(chǎn)生,比如:程序的行為異常、資源使用過(guò)量、或者不一致性的結(jié)果。

使用單例模式的好處:

  • 對(duì)于頻繁使用的對(duì)象,可以省略創(chuàng)建對(duì)象所花費(fèi)的時(shí)間,這對(duì)于那些重量級(jí)對(duì)象而言,是非常可觀的一筆系統(tǒng)開銷;
  • 由于 new 操作的次數(shù)減少,因而對(duì)系統(tǒng)內(nèi)存的使用頻率也會(huì)降低,這將減輕 GC 壓力,縮短 GC 停頓時(shí)間。

Spring 中 bean 的默認(rèn)作用域就是 singleton(單例)的。 除了 singleton 作用域,Spring 中 bean 還有下面幾種作用域:

  • prototype : 每次請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的 bean 實(shí)例。
  • request : 每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean,該bean僅在當(dāng)前HTTP request內(nèi)有效。
  • session : 每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的 bean,該bean僅在當(dāng)前 HTTP session 內(nèi)有效。
  • global-session: 全局session作用域,僅僅在基于portlet的web應(yīng)用中才有意義,Spring5已經(jīng)沒(méi)有了。Portlet是能夠生成語(yǔ)義代碼(例如:HTML)片段的小型Java Web插件。它們基于portlet容器,可以像servlet一樣處理HTTP請(qǐng)求。但是,與 servlet 不同,每個(gè) portlet 都有不同的會(huì)話

Spring 實(shí)現(xiàn)單例的方式:

  • xml : <bean id="userService" class="top.snailclimb.UserService" scope="singleton"/>
  • 注解:@Scope(value = "singleton")

Spring 通過(guò) ConcurrentHashMap 實(shí)現(xiàn)單例注冊(cè)表的特殊方式實(shí)現(xiàn)單例模式。Spring 實(shí)現(xiàn)單例的核心代碼如下

  1. // 通過(guò) ConcurrentHashMap(線程安全) 實(shí)現(xiàn)單例注冊(cè)表 
  2. private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64); 
  3.  
  4. public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { 
  5.         Assert.notNull(beanName, "'beanName' must not be null"); 
  6.         synchronized (this.singletonObjects) { 
  7.             // 檢查緩存中是否存在實(shí)例   
  8.             Object singletonObject = this.singletonObjects.get(beanName); 
  9.             if (singletonObject == null) { 
  10.                 //...省略了很多代碼 
  11.                 try { 
  12.                     singletonObject = singletonFactory.getObject(); 
  13.                 } 
  14.                 //...省略了很多代碼 
  15.                 // 如果實(shí)例對(duì)象在不存在,我們注冊(cè)到單例注冊(cè)表中。 
  16.                 addSingleton(beanName, singletonObject); 
  17.             } 
  18.             return (singletonObject != NULL_OBJECT ? singletonObject : null); 
  19.         } 
  20.     } 
  21.     //將對(duì)象添加到單例注冊(cè)表 
  22.     protected void addSingleton(String beanName, Object singletonObject) { 
  23.             synchronized (this.singletonObjects) { 
  24.                 this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); 
  25.  
  26.             } 
  27.         } 
  28. 復(fù)制代碼 

代理設(shè)計(jì)模式

代理模式在 AOP 中的應(yīng)用

AOP(Aspect-Oriented Programming:面向切面編程)能夠?qū)⒛切┡c業(yè)務(wù)無(wú)關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任(例如事務(wù)處理、日志管理、權(quán)限控制等)封裝起來(lái),便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來(lái)的可拓展性和可維護(hù)性

Spring AOP 就是基于動(dòng)態(tài)代理的,如果要代理的對(duì)象,實(shí)現(xiàn)了某個(gè)接口,那么Spring AOP會(huì)使用JDK Proxy,去創(chuàng)建代理對(duì)象,而對(duì)于沒(méi)有實(shí)現(xiàn)接口的對(duì)象,就無(wú)法使用 JDK Proxy 去進(jìn)行代理了,這時(shí)候Spring AOP會(huì)使用Cglib ,這時(shí)候Spring AOP會(huì)使用 Cglib 生成一個(gè)被代理對(duì)象的子類來(lái)作為代理,如下圖所示:

面試官:談?wù)凷pring中都用到了那些設(shè)計(jì)模式?

當(dāng)然你也可以使用 AspectJ ,Spring AOP 已經(jīng)集成了AspectJ ,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了。

使用 AOP 之后我們可以把一些通用功能抽象出來(lái),在需要用到的地方直接使用即可,這樣大大簡(jiǎn)化了代碼量。我們需要增加新功能時(shí)也方便,這樣也提高了系統(tǒng)擴(kuò)展性。日志功能、事務(wù)管理等等場(chǎng)景都用到了 AOP 。

Spring AOP 和 AspectJ AOP 有什么區(qū)別?

Spring AOP 屬于運(yùn)行時(shí)增強(qiáng),而 AspectJ 是編譯時(shí)增強(qiáng)。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字節(jié)碼操作(Bytecode Manipulation)。

Spring AOP 已經(jīng)集成了 AspectJ ,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加強(qiáng)大,但是 Spring AOP 相對(duì)來(lái)說(shuō)更簡(jiǎn)單,

如果我們的切面比較少,那么兩者性能差異不大。但是,當(dāng)切面太多的話,最好選擇 AspectJ ,它比Spring AOP 快很多。

模板方法

模板方法模式是一種行為設(shè)計(jì)模式,它定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。 模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟的實(shí)現(xiàn)方式。

面試官:談?wù)凷pring中都用到了那些設(shè)計(jì)模式?
 
  1. public abstract class Template { 
  2.     //這是我們的模板方法 
  3.     public final void TemplateMethod(){ 
  4.         PrimitiveOperation1();   
  5.         PrimitiveOperation2(); 
  6.         PrimitiveOperation3(); 
  7.     } 
  8.  
  9.     protected void  PrimitiveOperation1(){ 
  10.         //當(dāng)前類實(shí)現(xiàn) 
  11.     } 
  12.      
  13.     //被子類實(shí)現(xiàn)的方法 
  14.     protected abstract void PrimitiveOperation2(); 
  15.     protected abstract void PrimitiveOperation3(); 
  16.  
  17. public class TemplateImpl extends Template { 
  18.  
  19.     @Override 
  20.     public void PrimitiveOperation2() { 
  21.         //當(dāng)前類實(shí)現(xiàn) 
  22.     } 
  23.      
  24.     @Override 
  25.     public void PrimitiveOperation3() { 
  26.         //當(dāng)前類實(shí)現(xiàn) 
  27.     } 
  28.  
  29. 復(fù)制代碼 

Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 結(jié)尾的對(duì)數(shù)據(jù)庫(kù)操作的類,它們就使用到了模板模式。一般情況下,我們都是使用繼承的方式來(lái)實(shí)現(xiàn)模板模式,但是 Spring 并沒(méi)有使用這種方式,而是使用Callback 模式與模板方法模式配合,既達(dá)到了代碼復(fù)用的效果,同時(shí)增加了靈活性。

觀察者模式

觀察者模式是一種對(duì)象行為型模式。它表示的是一種對(duì)象與對(duì)象之間具有依賴關(guān)系,當(dāng)一個(gè)對(duì)象發(fā)生改變的時(shí)候,這個(gè)對(duì)象所依賴的對(duì)象也會(huì)做出反應(yīng)。Spring 事件驅(qū)動(dòng)模型就是觀察者模式很經(jīng)典的一個(gè)應(yīng)用。Spring 事件驅(qū)動(dòng)模型非常有用,在很多場(chǎng)景都可以解耦我們的代碼。比如我們每次添加商品的時(shí)候都需要重新更新商品索引,這個(gè)時(shí)候就可以利用觀察者模式來(lái)解決這個(gè)問(wèn)題。

Spring 事件驅(qū)動(dòng)模型中的三種角色

事件角色

ApplicationEvent (org.springframework.context包下)充當(dāng)事件的角色,這是一個(gè)抽象類,它繼承了java.util.EventObject并實(shí)現(xiàn)了 java.io.Serializable接口。

Spring 中默認(rèn)存在以下事件,他們都是對(duì) ApplicationContextEvent 的實(shí)現(xiàn)(繼承自ApplicationContextEvent):

  • ContextStartedEvent:ApplicationContext 啟動(dòng)后觸發(fā)的事件;
  • ContextStoppedEvent:ApplicationContext 停止后觸發(fā)的事件;
  • ContextRefreshedEvent:ApplicationContext 初始化或刷新完成后觸發(fā)的事件;
  • ContextClosedEvent:ApplicationContext 關(guān)閉后觸發(fā)的事件。
面試官:談?wù)凷pring中都用到了那些設(shè)計(jì)模式?

事件監(jiān)聽者角色

ApplicationListener 充當(dāng)了事件監(jiān)聽者角色,它是一個(gè)接口,里面只定義了一個(gè) onApplicationEvent()方法來(lái)處理ApplicationEvent。ApplicationListener接口類源碼如下,可以看出接口定義看出接口中的事件只要實(shí)現(xiàn)了 ApplicationEvent就可以了。所以,在 Spring中我們只要實(shí)現(xiàn) ApplicationListener 接口實(shí)現(xiàn) onApplicationEvent() 方法即可完成監(jiān)聽事件

  1. package org.springframework.context; 
  2. import java.util.EventListener; 
  3. @FunctionalInterface 
  4. public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { 
  5.     void onApplicationEvent(E var1); 
  6. 復(fù)制代碼 

事件發(fā)布者角色

ApplicationEventPublisher 充當(dāng)了事件的發(fā)布者,它也是一個(gè)接口。

  1. @FunctionalInterface 
  2. public interface ApplicationEventPublisher { 
  3.     default void publishEvent(ApplicationEvent event) { 
  4.         this.publishEvent((Object)event); 
  5.     } 
  6.  
  7.     void publishEvent(Object var1); 
  8.  
  9. 復(fù)制代碼 

ApplicationEventPublisher 接口的publishEvent()這個(gè)方法在AbstractApplicationContext類中被實(shí)現(xiàn),閱讀這個(gè)方法的實(shí)現(xiàn),你會(huì)發(fā)現(xiàn)實(shí)際上事件真正是通過(guò)ApplicationEventMulticaster來(lái)廣播出去的。具體內(nèi)容過(guò)多,就不在這里分析了,后面可能會(huì)單獨(dú)寫一篇文章提到。

Spring 的事件流程總結(jié)

  1. 定義一個(gè)事件: 實(shí)現(xiàn)一個(gè)繼承自 ApplicationEvent,并且寫相應(yīng)的構(gòu)造函數(shù);
  2. 定義一個(gè)事件監(jiān)聽者:實(shí)現(xiàn) ApplicationListener 接口,重寫 onApplicationEvent() 方法;
  3. 使用事件發(fā)布者發(fā)布消息: 可以通過(guò) ApplicationEventPublisher 的 publishEvent() 方法發(fā)布消息。

Example:

  1. // 定義一個(gè)事件,繼承自ApplicationEvent并且寫相應(yīng)的構(gòu)造函數(shù) 
  2. public class DemoEvent extends ApplicationEvent{ 
  3.     private static final long serialVersionUID = 1L; 
  4.  
  5.     private String message; 
  6.  
  7.     public DemoEvent(Object source,String message){ 
  8.         super(source); 
  9.         this.message = message; 
  10.     } 
  11.  
  12.     public String getMessage() { 
  13.          return message; 
  14.           } 
  15.  
  16.      
  17. // 定義一個(gè)事件監(jiān)聽者,實(shí)現(xiàn)ApplicationListener接口,重寫 onApplicationEvent() 方法; 
  18. @Component 
  19. public class DemoListener implements ApplicationListener<DemoEvent>{ 
  20.  
  21.     //使用onApplicationEvent接收消息 
  22.     @Override 
  23.     public void onApplicationEvent(DemoEvent event) { 
  24.         String msg = event.getMessage(); 
  25.         System.out.println("接收到的信息是:"+msg); 
  26.     } 
  27.  
  28. // 發(fā)布事件,可以通過(guò)ApplicationEventPublisher  的 publishEvent() 方法發(fā)布消息。 
  29. @Component 
  30. public class DemoPublisher { 
  31.  
  32.     @Autowired 
  33.     ApplicationContext applicationContext; 
  34.  
  35.     public void publish(String message){ 
  36.         //發(fā)布事件 
  37.         applicationContext.publishEvent(new DemoEvent(this, message)); 
  38.     } 
  39.  
  40. 復(fù)制代碼 

當(dāng)調(diào)用 DemoPublisher 的 publish() 方法的時(shí)候,比如 demoPublisher.publish("你好") ,控制臺(tái)就會(huì)打印出:接收到的信息是:你好 。

適配器模式

適配器模式(Adapter Pattern) 將一個(gè)接口轉(zhuǎn)換成客戶希望的另一個(gè)接口,適配器模式使接口不兼容的那些類可以一起工作,其別名為包裝器(Wrapper)。

spring AOP中的適配器模式

我們知道 Spring AOP 的實(shí)現(xiàn)是基于代理模式,但是 Spring AOP 的增強(qiáng)或通知(Advice)使用到了適配器模式,與之相關(guān)的接口是AdvisorAdapter 。Advice 常用的類型有:BeforeAdvice(目標(biāo)方法調(diào)用前,前置通知)、AfterAdvice(目標(biāo)方法調(diào)用后,后置通知)、AfterReturningAdvice(目標(biāo)方法執(zhí)行結(jié)束后,return之前)等等。每個(gè)類型Advice(通知)都有對(duì)應(yīng)的攔截器:MethodBeforeAdviceInterceptor、AfterReturningAdviceAdapter、AfterReturningAdviceInterceptor。Spring預(yù)定義的通知要通過(guò)對(duì)應(yīng)的適配器,適配成 MethodInterceptor接口(方法攔截器)類型的對(duì)象(如:MethodBeforeAdviceInterceptor 負(fù)責(zé)適配 MethodBeforeAdvice)。

spring MVC中的適配器模式

在Spring MVC中,DispatcherServlet 根據(jù)請(qǐng)求信息調(diào)用 HandlerMapping,解析請(qǐng)求對(duì)應(yīng)的 Handler。解析到對(duì)應(yīng)的 Handler(也就是我們平常說(shuō)的 Controller 控制器)后,開始由HandlerAdapter 適配器處理。HandlerAdapter 作為期望接口,具體的適配器實(shí)現(xiàn)類用于對(duì)目標(biāo)類進(jìn)行適配,Controller 作為需要適配的類。

為什么要在 Spring MVC 中使用適配器模式? Spring MVC 中的 Controller 種類眾多,不同類型的 Controller 通過(guò)不同的方法來(lái)對(duì)請(qǐng)求進(jìn)行處理。如果不利用適配器模式的話,DispatcherServlet 直接獲取對(duì)應(yīng)類型的 Controller,需要的自行來(lái)判斷,像下面這段代碼一樣:

  1. if(mappedHandler.getHandler() instanceof MultiActionController){   
  2.    ((MultiActionController)mappedHandler.getHandler()).xxx   
  3. }else if(mappedHandler.getHandler() instanceof XXX){   
  4.     ...   
  5. }else if(...){   
  6.    ...   
  7. }   
  8. 復(fù)制代碼 

假如我們?cè)僭黾右粋€(gè) Controller類型就要在上面代碼中再加入一行 判斷語(yǔ)句,這種形式就使得程序難以維護(hù),也違反了設(shè)計(jì)模式中的開閉原則 – 對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。

裝飾者模式

裝飾者模式可以動(dòng)態(tài)地給對(duì)象添加一些額外的屬性或行為。相比于使用繼承,裝飾者模式更加靈活。簡(jiǎn)單點(diǎn)兒說(shuō)就是當(dāng)我們需要修改原有的功能,但我們又不愿直接去修改原有的代碼時(shí),設(shè)計(jì)一個(gè)Decorator套在原有代碼外面。其實(shí)在 JDK 中就有很多地方用到了裝飾者模式,比如 InputStream家族,InputStream 類下有 FileInputStream (讀取文件)、BufferedInputStream (增加緩存,使讀取文件速度大大提升)等子類都在不修改InputStream 代碼的情況下擴(kuò)展了它的功能。

面試官:談?wù)凷pring中都用到了那些設(shè)計(jì)模式?

Spring 中配置 DataSource 的時(shí)候,DataSource 可能是不同的數(shù)據(jù)庫(kù)和數(shù)據(jù)源。我們能否根據(jù)客戶的需求在少修改原有類的代碼下動(dòng)態(tài)切換不同的數(shù)據(jù)源?這個(gè)時(shí)候就要用到裝飾者模式(這一點(diǎn)我自己還沒(méi)太理解具體原理)。Spring 中用到的包裝器模式在類名上含有 Wrapper或者 Decorator。這些類基本上都是動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)

總結(jié)

Spring 框架中用到了哪些設(shè)計(jì)模式?

  • 工廠設(shè)計(jì)模式 : Spring使用工廠模式通過(guò) BeanFactory、ApplicationContext 創(chuàng)建 bean 對(duì)象。
  • 代理設(shè)計(jì)模式 : Spring AOP 功能的實(shí)現(xiàn)。
  • 單例設(shè)計(jì)模式 : Spring 中的 Bean 默認(rèn)都是單例的。
  • 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 結(jié)尾的對(duì)數(shù)據(jù)庫(kù)操作的類,它們就使用到了模板模式。
  • 包裝器設(shè)計(jì)模式 : 我們的項(xiàng)目需要連接多個(gè)數(shù)據(jù)庫(kù),而且不同的客戶在每次訪問(wèn)中根據(jù)需要會(huì)去訪問(wèn)不同的數(shù)據(jù)庫(kù)。這種模式讓我們可以根據(jù)客戶的需求能夠動(dòng)態(tài)切換不同的數(shù)據(jù)源。
  • 觀察者模式: Spring 事件驅(qū)動(dòng)模型就是觀察者模式很經(jīng)典的一個(gè)應(yīng)用。
  • 適配器模式 :Spring AOP 的增強(qiáng)或通知(Advice)使用到了適配器模式、spring MVC 中也是用到了適配器模式適配Controller。

 

 

責(zé)任編輯:張燕妮 來(lái)源: 今日頭條
相關(guān)推薦

2019-05-29 17:20:07

Spring設(shè)計(jì)模式Java

2023-07-11 08:50:34

2022-09-21 09:01:27

Spring設(shè)計(jì)模式框架,

2021-05-31 07:58:59

Spring設(shè)計(jì)模式

2024-08-16 13:59:00

2021-06-08 07:04:46

Dubbo設(shè)計(jì)模式

2024-11-26 14:29:48

2024-05-30 07:37:30

2020-01-02 15:43:29

Spring設(shè)計(jì)策略

2025-05-09 09:05:00

Spring框架設(shè)計(jì)模式

2015-01-05 09:53:05

Java

2022-02-23 19:38:22

物聯(lián)網(wǎng)通信協(xié)議

2021-10-27 17:57:35

設(shè)計(jì)模式場(chǎng)景

2023-10-04 07:27:33

WebPhotoshop

2017-11-01 10:31:08

Docker

2021-08-14 08:17:49

Android設(shè)計(jì)模式OKHttp

2025-05-12 07:43:14

SpringMVC設(shè)計(jì)模式代碼

2021-08-11 17:22:11

設(shè)計(jì)模式單例

2015-01-14 13:26:58

AndroidJava單例

2017-03-20 18:03:51

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91精品在线播放 | 一级a毛片 | 91久久综合亚洲鲁鲁五月天 | 国产欧美日韩一区二区三区 | 尤物在线 | 99精品99| 精品亚洲一区二区三区 | 91精品一区二区三区久久久久 | 国内在线视频 | av片毛片| 免费视频一区二区 | 一区在线视频 | 国产精品99999 | 日韩另类视频 | 97国产超碰| 一级黄在线观看 | 九九精品视频在线 | 欧美日韩一区二区三区四区五区 | 色网站视频 | 中文字幕一区二区三区精彩视频 | 日韩在线观看中文字幕 | 伊人一二三 | 美女张开腿露出尿口 | av一二三区 | 黄色在线播放视频 | 国产精品一区二区在线播放 | 亚洲综合精品 | 亚洲激情av | 欧美8一10sex性hd | 亚洲精品1区 | 成人精品国产 | 国产成人免费视频网站视频社区 | 在线不卡视频 | 欧美久久久久久久久中文字幕 | 亚洲精品一区二区三区蜜桃久 | 男女视频在线观看免费 | 国产亚洲精品久久久优势 | 日韩欧美福利视频 | 一区二区三区四区电影视频在线观看 | 狠狠爱免费视频 | 中文字幕国产第一页 |