IT總結(jié) | Spring鲁豪、SpringMVC、SpringBoot律秃、SpringCloud之間的關(guān)系

Spring與SpringMVC

Spring是一個(gè)一站式的框架爬橡,提供了表現(xiàn)層(SpringMVC/Struts)到業(yè)務(wù)層(Spring)再到數(shù)據(jù)層(Hibernate/Mybatis)都提供了多種配置解決方案;Spring的兩大核心IOC(控制反轉(zhuǎn))和AOP(面向切面編程)更是給我們的程序解耦和代碼的簡(jiǎn)介提供了支持棒动。

即Spring在JavaEE的三層架構(gòu)[表現(xiàn)層(Web層)糙申、業(yè)務(wù)邏輯層(Service層)、數(shù)據(jù)訪問層(DAO層)]中船惨,每一層均提供了不同的解決技術(shù)柜裸。如下:
? 表現(xiàn)層(Web層):Spring MVC
? 業(yè)務(wù)邏輯層(Service層):Spring的IoC
? 數(shù)據(jù)訪問層(DAO層):Spring的jdbcTemplate

Spring是IOC和AOP的容器框架,SpringMVC是基于Spring功能之上添加的Web框架掷漱,想用SpringMVC必須先依賴Spring粘室。

Spring MVC通過Dispatcher Servlet, ModelAndView 和 View Resolver,開發(fā)web應(yīng)用變得很容易卜范。主要針對(duì)的是網(wǎng)站應(yīng)用程序或者服務(wù)開發(fā)——URL路由衔统、Session、模板引擎海雪、靜態(tài)Web資源等等锦爵。

  • SpringMVC的執(zhí)行流程

1、 用戶發(fā)送請(qǐng)求至前端控制器DispatcherServlet奥裸;
2险掀、DispatcherServlet收到請(qǐng)求調(diào)用HandlerMapping處理器映射器;
3湾宙、處理器映射器根據(jù)請(qǐng)求url找到具體的處理器樟氢,生成處理器對(duì)象及處理器攔截器(如果有則生成)一并返回給DispatcherServlet冈绊;
4、DispatcherServlet通過HandlerAdapter處理器適配器調(diào)用處理器埠啃,執(zhí)行處理器(Controller死宣,也叫后端控制器);
5碴开、Controller執(zhí)行完成返回ModelAndView毅该,并返回給HandlerAdapter,HandlerAdapter將結(jié)果返回給DispatcherServlet潦牛;
6眶掌、DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器,ViewReslover解析后返回具體View給DispatcherServlet巴碗;
7朴爬、DispatcherServlet對(duì)View進(jìn)行渲染視圖(即將模型數(shù)據(jù)填充至視圖中)后返回給給客戶

  • Spring的優(yōu)點(diǎn)

1、降低了組件之間的耦合性 良价,實(shí)現(xiàn)了軟件各層之間的解耦
2寝殴、容器提供單例模式支持
????在Spring中,bean可以被定義為兩種模式:prototype(多例)和singleton(單例), 默認(rèn)是單例模式明垢。
????2.1蚣常、singleton(單例):只有一個(gè)共享的實(shí)例存在,所有對(duì)這個(gè)bean的請(qǐng)求都會(huì)返回這個(gè)唯一的實(shí)例痊银。
????2.2抵蚊、prototype(多例):對(duì)這個(gè)bean的每次請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的bean實(shí)例,類似于new溯革。
3贞绳、容器提供了AOP技術(shù),利用它很容易實(shí)現(xiàn)如權(quán)限攔截致稀,運(yùn)行期監(jiān)控等功能
4冈闭、Spring對(duì)于主流的應(yīng)用框架提供了集成支持,如hibernate抖单,JPA萎攒,Struts等
5、spring的DI機(jī)制降低了業(yè)務(wù)對(duì)象替換的復(fù)雜性

  • 什么是DI機(jī)制矛绘?

依賴注入(Dependecy Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個(gè)概念耍休,具體的講:當(dāng)某個(gè)角色需要另外一個(gè)角色協(xié)助的時(shí)候,在傳統(tǒng)的程序設(shè)計(jì)過程中货矮,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實(shí)例羊精。

但在Spring中創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來完成,因此稱為控制反轉(zhuǎn)囚玫。創(chuàng)建被調(diào)用者的工作由Spring來完成喧锦,然后注入調(diào)用者因此也稱為依賴注入读规。

Spring以動(dòng)態(tài)靈活的方式來管理對(duì)象 , 注入的兩種方式燃少,設(shè)置注入和構(gòu)造注入掖桦。
設(shè)置注入的優(yōu)點(diǎn):直觀,自然
構(gòu)造注入的優(yōu)點(diǎn):可以在構(gòu)造器中決定依賴關(guān)系的順序供汛。

  • Spring的IOC

Spring IOC(控制反轉(zhuǎn),也可以稱為依賴倒置)涌穆,將傳統(tǒng)的對(duì)象創(chuàng)建流程轉(zhuǎn)變?yōu)榻挥蒘pring框架進(jìn)行創(chuàng)建和管理怔昨。Spring IOC操作分為:IOC配置文件方式和IOC的注解方式。

  • Spring的AOP

面向切面編程(AOP)是對(duì)面向?qū)ο缶幊蹋∣OP)的補(bǔ)充宿稀,面向切面編程在Spring中主要表現(xiàn)為兩個(gè)方面:
1趁舀、面向切面編程提供聲明式事務(wù)管理
2、Spring支持用戶自定義的切面

AOP采取橫向抽取機(jī)制祝沸,取代了傳統(tǒng)縱向繼承體系重復(fù)性代碼矮烹,例如:事務(wù)管理、性能監(jiān)視罩锐、安全檢查奉狈、緩存 、日志等涩惑。

AOP實(shí)現(xiàn)原理:
1仁期、AOP底層將采用代理機(jī)制進(jìn)行實(shí)現(xiàn)。
2竭恬、接口 + 實(shí)現(xiàn)類 :Spring采用 JDK的動(dòng)態(tài)代理Proxy跛蛋。
3、實(shí)現(xiàn)類:Spring采用 Cglib字節(jié)碼增強(qiáng)痊硕。

JDK動(dòng)態(tài)代理

public static UserService createService(){
        //1 目標(biāo)類
        final UserService userService = new UserServiceImpl();
        //2切面類
        final MyAspect aspect = new MyAspect();
        /* 3 代理類:將目標(biāo)類(切入點(diǎn))和 切面類(通知) 結(jié)合 --> 切面
         *  Proxy.newProxyInstance
         *      參數(shù)1:loader 赊级,類加載器,動(dòng)態(tài)代理類 運(yùn)行時(shí)創(chuàng)建岔绸,任何類都需要類加載器將其加載到內(nèi)存理逊。
         *          一般情況:當(dāng)前類.class.getClassLoader();
         *                  目標(biāo)類實(shí)例.getClass().get...
         *      參數(shù)2:Class[] interfaces 代理類需要實(shí)現(xiàn)的所有接口
         *          方式1:目標(biāo)類實(shí)例.getClass().getInterfaces()  ;注意:只能獲得自己接口,不能獲得父元素接口
         *          方式2:new Class[]{UserService.class}   
         *          例如:jdbc 驅(qū)動(dòng)  --> DriverManager  獲得接口 Connection
         *      參數(shù)3:InvocationHandler  處理類亭螟,接口挡鞍,必須進(jìn)行實(shí)現(xiàn)類,一般采用匿名內(nèi)部
         *          提供 invoke 方法预烙,代理類的每一個(gè)方法執(zhí)行時(shí)墨微,都將調(diào)用一次invoke
         *              參數(shù)31:Object proxy :代理對(duì)象
         *              參數(shù)32:Method method : 代理對(duì)象當(dāng)前執(zhí)行的方法的描述對(duì)象(反射)
         *                  執(zhí)行方法名:method.getName()
         *                  執(zhí)行方法:method.invoke(對(duì)象,實(shí)際參數(shù))
         *              參數(shù)33:Object[] args :方法實(shí)際參數(shù)
         * 
         */
        UserService proxyService = (UserService)Proxy.newProxyInstance(
                                MyBeanFactory.class.getClassLoader(), 
                                userService.getClass().getInterfaces(), 
                                new InvocationHandler() {
                                    @Override
                                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                        //前執(zhí)行
                                        aspect .before();
                                        //執(zhí)行目標(biāo)類的方法
                                        Object obj = method.invoke(userService, args);
                                        //后執(zhí)行
                                        aspect .after();
                                        return obj;
                                    }
                                });
        return proxyService;
    }

Spring的CGLIB字節(jié)碼增強(qiáng)

public static UserServiceImpl createService(){
        //1 目標(biāo)類
        final UserServiceImpl userService = new UserServiceImpl();
        //2切面類
        final MyAspect myAspect = new MyAspect();
        // 3.代理類 扁掸,采用cglib翘县,底層創(chuàng)建目標(biāo)類的子類
        //3.1 核心類
        Enhancer enhancer = new Enhancer();
        //3.2 確定父類
        enhancer.setSuperclass(userService.getClass());
        /* 3.3 設(shè)置回調(diào)函數(shù) , MethodInterceptor接口 等效 jdk InvocationHandler接口
         *  intercept() 等效 jdk  invoke()
         *      參數(shù)1最域、參數(shù)2、參數(shù)3:以invoke一樣
         *      參數(shù)4:methodProxy 方法的代理
         */
        enhancer.setCallback(new MethodInterceptor(){
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //前執(zhí)行
                myAspect.before();
                //執(zhí)行目標(biāo)類的方法
                Object obj = method.invoke(userService, args);
                // * 執(zhí)行代理類的父類 锈麸,執(zhí)行目標(biāo)類 (目標(biāo)類和代理類 父子關(guān)系)
                methodProxy.invokeSuper(proxy, args);
                //后執(zhí)行
                myAspect.after();

                return obj;
            }
        });
        //3.4 創(chuàng)建代理
        UserServiceImpl proxService = (UserServiceImpl) enhancer.create();

        return proxService;
    }

注解方式

/*
 * 聲明一個(gè)切面
 * 自動(dòng)注解AOP
 */
@Aspect
@Component(value="aopDemoOrder")
public class AopDemoOrder {
    // 配置切點(diǎn) 及要傳的參數(shù)   
    @Pointcut("execution(* com.spring.aop.OrderService.GetDemoOrder(..)) && args(id)")
    public void pointCut(int id)
    {

    }

    // 配置連接點(diǎn) 方法開始執(zhí)行前通知
    @Before("pointCut(id)")
    public void beforeLog(int id) {
        System.out.println("開始執(zhí)行前置通知  日志記錄:"+id);
    }
    // 方法執(zhí)行完后通知
    @After("pointCut(id)")
    public void afterLog(int id) {
        System.out.println("方法執(zhí)行完后置通知 日志記錄:"+id);
    }
    // 執(zhí)行成功后通知
    @AfterReturning("pointCut(id)")
    public void afterReturningLog(int id) {
        System.out.println("方法成功執(zhí)行后通知 日志記錄:"+id);
    }
    // 拋出異常后通知
    @AfterThrowing("pointCut(id)")
    public void afterThrowingLog(int id) {
        System.out.println("方法拋出異常后通知 日志記錄"+id);
    }

    // 環(huán)繞通知
    @Around("pointCut(id)")
    public Object aroundLog(ProceedingJoinPoint joinpoint, int id) {
        Object result = null;
        try {
            System.out.println("環(huán)繞通知開始 日志記錄"+id);
            long start = System.currentTimeMillis();

            //有返回參數(shù) 則需返回值
            result = joinpoint.proceed();
        } catch (Throwable t) {
            System.out.println("出現(xiàn)錯(cuò)誤");
        }
        return result;
    }    
}
  • BeanFactory與FactoryBean

1镀脂、BeanFactory是個(gè)Factory,也就是IOC容器或?qū)ο蠊S忘伞。在Spring中薄翅,所有的Bean都是由BeanFactory(也就是IOC容器)來進(jìn)行管理的。
2氓奈、FactoryBean是Spring通過反射機(jī)制利用<bean>的class屬性指定實(shí)現(xiàn)類實(shí)例化Bean翘魄,在某些情況下,實(shí)例化Bean過程比較復(fù)雜舀奶,如果按照傳統(tǒng)的方式暑竟,則需要在<bean>中提供大量的配置信息。Spring為此提供了一個(gè)org.springframework.bean.factory.FactoryBean的工廠類接口育勺,用戶可以通過實(shí)現(xiàn)該接口定制實(shí)例化Bean的邏輯但荤。

SpringBoot與SpringCloud

Spring Boot,看名字就知道是Spring的一套快速配置腳手架涧至,可以基于Spring Boot快速開發(fā)單個(gè)微服務(wù)腹躁。

Spring Cloud基于Spring Boot,為微服務(wù)體系開發(fā)中的架構(gòu)問題南蓬,提供了一整套的解決方案——服務(wù)注冊(cè)與發(fā)現(xiàn)潜慎,服務(wù)消費(fèi),服務(wù)保護(hù)與熔斷蓖康,網(wǎng)關(guān)铐炫,分布式調(diào)用追蹤,分布式配置管理等蒜焊。

Spring Boot可以離開Spring Cloud獨(dú)立使用開發(fā)項(xiàng)目倒信,但是Spring Cloud離不開Spring Boot,屬于依賴的關(guān)系泳梆。

總結(jié)

1鳖悠、 Spring 框架就像一個(gè)家族,有眾多衍生產(chǎn)品例如 boot优妙、security乘综、jpa等等。但他們的基礎(chǔ)都是Spring的IOC套硼、AOP等卡辰, IOC提供了依賴注入的容器, AOP解決了面向橫切面編程,然后在此兩者的基礎(chǔ)上實(shí)現(xiàn)了其他延伸產(chǎn)品的高級(jí)功能九妈;
2反砌、 SpringMVC是基于Servlet 的一個(gè)MVC框架主要解決Web開發(fā)的問題,因?yàn)镾pring的配置非常復(fù)雜萌朱,各種XML宴树、JavaConfig、servlet處理起來比較繁瑣晶疼;
3酒贬、為了簡(jiǎn)化開發(fā)者的使用,推出了Spring Boot框架默認(rèn)優(yōu)于配置翠霍,簡(jiǎn)化了SpringMVC的配置流程同衣;但區(qū)別于SpringBoot專注于微服務(wù)方面的接口開發(fā),和前端解耦壶运,雖然SpringBoot也可以做成SpringMVC前后臺(tái)一起開發(fā),但是這就有點(diǎn)不符合SpringBoot框架的初衷了浪秘;
4.蒋情、SpringCloud關(guān)注的是全局微服務(wù)的整合和管理,相當(dāng)于管理多個(gè)SpringBoot框架的單體微服務(wù)耸携;為微服務(wù)體系開發(fā)中的架構(gòu)問題棵癣,提供了一整套的解決方案。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夺衍,一起剝皮案震驚了整個(gè)濱河市狈谊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沟沙,老刑警劉巖河劝,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異矛紫,居然都是意外死亡赎瞎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門颊咬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來务甥,“玉大人,你說我怎么就攤上這事喳篇〕伲” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵麸澜,是天一觀的道長(zhǎng)挺尿。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么票髓? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任攀涵,我火速辦了婚禮,結(jié)果婚禮上洽沟,老公的妹妹穿的比我還像新娘以故。我一直安慰自己,他們只是感情好裆操,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布怒详。 她就那樣靜靜地躺著,像睡著了一般踪区。 火紅的嫁衣襯著肌膚如雪昆烁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天缎岗,我揣著相機(jī)與錄音静尼,去河邊找鬼。 笑死传泊,一個(gè)胖子當(dāng)著我的面吹牛鼠渺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播眷细,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼拦盹,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了溪椎?” 一聲冷哼從身側(cè)響起普舆,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎校读,沒想到半個(gè)月后沼侣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歉秫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年华临,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片端考。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雅潭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出却特,到底是詐尸還是另有隱情扶供,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布裂明,位于F島的核電站椿浓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扳碍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一提岔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笋敞,春花似錦碱蒙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至趁餐,卻和暖如春喷兼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背后雷。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工季惯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人臀突。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓勉抓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親惧辈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容