<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring必知必會(huì),底層都使用了哪些設(shè)計(jì)模式?

          共 11515字,需瀏覽 24分鐘

           ·

          2021-09-16 14:38

            Spring用到的設(shè)計(jì)模式   


          1

          代理模式:最常見的 AOP 的實(shí)現(xiàn)方式就是通過(guò)代理來(lái)實(shí)現(xiàn),Spring主要是使用 JDK 動(dòng)態(tài)代理和 CGLIB 代理。


          其中JDK代理實(shí)現(xiàn)代碼如下所示:


          public class ProxyHandler implements InvocationHandler {
          Object target; public ProxyHandler(Object target) { this.target=target; } public void before(String param) throws Throwable { if(!param.equals("magicalwolf")) throw new IllegalArgumentException(); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before((String)args[0]); return method.invoke(target, args); }}
          public class Main { public static void main(String[] args) { Subject target=new RealSubject(); Subject proxy=(Subject)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new ProxyHandler(target)); proxy.request("magicalwolf"); proxy.request("hello"); }}


          CGLIB代理實(shí)現(xiàn)如下:


          public class RequestInterceptor implements MethodInterceptor {
          public void before(String param) throws Throwable { if(!param.equals("hello")) throw new IllegalArgumentException(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { before((String)args[0]); return proxy.invokeSuper(obj, args);//調(diào)用父類的方法 }}
          public class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); //字節(jié)碼增強(qiáng)器 enhancer.setSuperclass(RealSubject.class); //代理類 enhancer.setCallback(new RequestInterceptor());//回調(diào)方法 Subject proxy = (Subject) enhancer.create(); proxy.request("hello"); }}


          2

          模版模式:定義了一個(gè)在操作中的算法框架,而將一些具體步驟延遲到子類中,使子類看可以在不改變算法結(jié)構(gòu)下即可重新定義該算法的某些特定步驟。


          主要是一些對(duì)數(shù)據(jù)庫(kù)操作的類用到,比如 JdbcTemplate、JpaTemplate,因?yàn)椴樵償?shù)據(jù)庫(kù)的建立連接、執(zhí)行查詢、關(guān)閉連接幾個(gè)過(guò)程,非常適用于模板方法。



          //提交事務(wù)protected abstract void doCommit(DefaultTransactionStatus status); //回滾事務(wù)protected abstract void doRollback(DefaultTransactionStatus status); //開始事務(wù)protected abstract void doBegin(Object transaction, TransactionDefinition definition) //獲取當(dāng)前的事務(wù)對(duì)象protected abstract Object doGetTransaction()


          Spring框架啟動(dòng)也遵循如準(zhǔn)備啟動(dòng)上下文,初始化BeanFactory、BeanFactory對(duì)象的前置處理與注冊(cè),消息發(fā)送器初始化,發(fā)送應(yīng)用啟動(dòng)消息等等特定的特定啟動(dòng)流程,將BeanFactory的初始化和刷新留在了具體的應(yīng)用實(shí)現(xiàn)類去實(shí)現(xiàn)。


          public abstract class AbstractApplicationContext extends DefaultResourceLoader      implements ConfigurableApplicationContext {         @Override    public void refresh() throws BeansException, IllegalStateException {          prepareRefresh();            //子類實(shí)現(xiàn)初始化BeanFactory對(duì)象       ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();             prepareBeanFactory(beanFactory);            postProcessBeanFactory(beanFactory);            invokeBeanFactoryPostProcessors(beanFactory);            registerBeanPostProcessors(beanFactory);            initMessageSource();            initApplicationEventMulticaster();            onRefresh();            registerListeners();            finishBeanFactoryInitialization(beanFactory);            finishRefresh();  }    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {    refreshBeanFactory();    return getBeanFactory();  }  
          // 兩個(gè)抽象方法 public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException; protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;}



          3

          工廠模式:定義了用于創(chuàng)建對(duì)象的接口,讓子類決定要?jiǎng)?chuàng)建哪個(gè)類的實(shí)例化,可以促進(jìn)組件或類之間的松耦合,通過(guò)使用接口而不是將特定的類綁定到應(yīng)用程序代碼中。


          Spring框架使用工廠模式實(shí)現(xiàn)了 BeanFactory 和 ApplicationContext 接口,基于工廠模式為Spring應(yīng)用程序創(chuàng)建Bean,并管理著每一個(gè)Bean的生命周期。如BeanFactory實(shí)例中的doGetBean方法可以根據(jù)使用者傳入的名字,類型,參數(shù)等生成對(duì)象并返回。


          public class StaticListableBeanFactory implements ListableBeanFactory {
          private final Map<String, Object> beans; protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
          String beanName = transformedBeanName(name); Object beanInstance;
          Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); } }


          4

          單例模式:保證了一個(gè)類僅有的一個(gè)實(shí)例,并提供了一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn),提供控制器對(duì)關(guān)鍵類的訪問(wèn)。


          單例模式如DB的連接類或Hibernate中的SessionFactory類,節(jié)省了大量的內(nèi)存,Spring框架中的Bean對(duì)象默認(rèn)都是為單例,在Bean對(duì)象注冊(cè)器實(shí)例上使用了Map來(lái)管理Bean對(duì)象,每次獲取到的對(duì)象是從該單例容器中取出來(lái)的。



          public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } } } return singletonObject; } }


          5

          責(zé)任鏈可以避免發(fā)送者與請(qǐng)求者耦合在一起,讓多個(gè)對(duì)象都有可能接收到請(qǐng)求,將這些對(duì)象連接成一條鏈,并且沿著這條鏈路傳遞請(qǐng)求,直到有對(duì)象處理為止。


          Spring中的Filter實(shí)現(xiàn)了責(zé)任鏈模式,管理者所有的Filter的順序執(zhí)行,可以對(duì)同一種對(duì)象資源實(shí)現(xiàn)不同業(yè)務(wù)場(chǎng)景的處理,達(dá)到業(yè)務(wù)解耦。詳情可參考以下鏈接。


          https://blog.csdn.net/lovejj1994/article/details/87457581

          public final class ApplicationFilterChain implements FilterChain {
          private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0]; private int pos = 0; private int n = 0; @Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { internalDoFilter(request,response); }
          private void internalDoFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { if (pos < n) { ApplicationFilterConfig filterConfig = filters[pos++]; Filter filter = filterConfig.getFilter(); filter.doFilter(request, response, this); } } }


          6

          觀察者模式: 定義了對(duì)象之間一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都能得到通知并自動(dòng)更新。


          在Spring框架中,觀察者用于實(shí)現(xiàn)ApplicationContext的事件處理功能,為開發(fā)者提供了ApplicationEvent和ApplicationLIstneter接口來(lái)啟用事件處理,任何Bean實(shí)現(xiàn)了SpringListner接口都會(huì)收到ApplicationEvent作為事件發(fā)布者推送的消息。更多詳情可參考以下鏈接。


          https://zhuanlan.zhihu.com/p/101141124


          @Servicepublic class PublishService {
          @Autowired private ApplicationContext applicationContext;
          public void publishEvent() { applicationContext.publishEvent(new TestSuccessEvent(this)); }}

          @Servicepublic class ListenService {
          @EventListener(TestSuccessEvent.class) public void test() { .... }}
          @Configurationpublic class AsyncEventConfig {
          @Bean(name = "applicationEventMulticaster") public ApplicationEventMulticaster simpleApplicationEventMulticaster() { SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster(); eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor()); return eventMulticaster; }
          }
          public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
          ..... @Override public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); Executor executor = getTaskExecutor(); for (ApplicationListener<?> listener : getApplicationListeners(event, type)) { if (executor != null) { executor.execute(() -> invokeListener(listener, event)); } else { invokeListener(listener, event); } } } .....}


          7

          適配器模式:將一個(gè)類的接口轉(zhuǎn)換成希望的另外一個(gè)接口,Spring框架使用適配器模式實(shí)現(xiàn)了很多功能,常見的適配器模式的類有 配置適配器RequestMappinghandlerAdapter完成了從請(qǐng)求到方法的映射,返回值到對(duì)應(yīng)的視圖或頁(yè)面的適配轉(zhuǎn)換。


            public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {        @Bean    public RequestMappingHandlerAdapter requestMappingHandlerAdapter(        @Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,        @Qualifier("mvcConversionService") FormattingConversionService conversionService,        @Qualifier("mvcValidator") Validator validator) {
          RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter(); ..... return adapter; }}

          public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean { @Override protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
          ModelAndView mav; checkRequest(request); if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { mav = invokeHandlerMethod(request, response, handlerMethod); } } else { mav = invokeHandlerMethod(request, response, handlerMethod); } } else { mav = invokeHandlerMethod(request, response, handlerMethod); }
          if (!response.containsHeader(HEADER_CACHE_CONTROL)) { if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { prepareResponse(response); } }
          return mav; } }


          8

          建造者模式: 可以一步步構(gòu)建一個(gè)復(fù)雜的對(duì)象,最終將返回完整的對(duì)象,對(duì)象創(chuàng)建的邏輯和過(guò)程是通用的,使用它來(lái)創(chuàng)建相同的類型的不同具體實(shí)現(xiàn),隱藏了調(diào)用方調(diào)用代碼時(shí)構(gòu)建對(duì)象的細(xì)節(jié)。


          Spring框架中有一些功能實(shí)現(xiàn)了建造者模式如EmbeddedDatabaseBuilder、BeanDefinitionBuilder、MockMvcWebClientBuilder等。


          public class EmbeddedDatabaseBuilder {
          ...... public EmbeddedDatabaseBuilder setName(String databaseName) { this.databaseFactory.setDatabaseName(databaseName); return this; }
          public EmbeddedDatabaseBuilder setType(EmbeddedDatabaseType databaseType) { this.databaseFactory.setDatabaseType(databaseType); return this; }
          public EmbeddedDatabaseBuilder setDataSourceFactory(DataSourceFactory dataSourceFactory) { Assert.notNull(dataSourceFactory, "DataSourceFactory is required"); this.databaseFactory.setDataSourceFactory(dataSourceFactory); return this; }
          ......}


            IOC和AOP的理解   


          IOC 叫做控制反轉(zhuǎn)。指的是通過(guò)Spring來(lái)管理對(duì)象的創(chuàng)建、配置和生命周期,這樣相當(dāng)于把控制權(quán)交給了Spring,不需要人工來(lái)管理對(duì)象之間復(fù)雜的依賴關(guān)系,這樣做的好處就是解耦。


          在Spring里面,主要提供了 BeanFactory 和 ApplicationContext 兩種 IOC 容器。


          AOP 叫做面向切面編程。是一個(gè)編程范式,目的就是提高代碼的模塊性。


          Spring AOP 基于動(dòng)態(tài)代理的方式實(shí)現(xiàn),如果是實(shí)現(xiàn)了接口的話就會(huì)使用 JDK 動(dòng)態(tài)代理,反之則使用 CGLIB 代理。


          Spring中, AOP 的應(yīng)用主要體現(xiàn)在事務(wù)、日志、異常處理等方面,通過(guò)在代碼的前后做一些增強(qiáng)處理,可以實(shí)現(xiàn)對(duì)業(yè)務(wù)邏輯的隔離,提高代碼的模塊化能力,同時(shí)也是解耦。Spring主要提供了 Aspect 切面、JoinPoint 連接點(diǎn)、PointCut 切入點(diǎn)、Advice 增強(qiáng)等實(shí)現(xiàn)方式。


            幾種代理方式的實(shí)現(xiàn)方式與區(qū)別   




          Spring必知必會(huì)上篇完,下篇內(nèi)容預(yù)告:


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

          • 5.Spring框架的主要模塊

          • Bean的生命周期

            ……

            ……




          更多干貨請(qǐng)點(diǎn)擊關(guān)注


          瀏覽 64
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美精品亚洲精品日韩已满 | 久久精品毛片 | 国产操网| 操小逼逼 | 日韩乱轮小说与视频 |