天天看點

struts2/ springmvc/ spring/ mybatis/ springboot/ springclound架構小總結

struts2:

是SSH架構集中的架構之一,是一個基于mvc設計模式的web應用架構,它本質上相當于一個servlet,在MVC設計模式中,struts2作為控制器層來建立模型與視圖的資料互動。

需要兩個配置檔案,分别為web.xml和struts.xml,

一、通路流程:

(1)用戶端送出請求

(2)請求被送出到一系列過濾器(先ActionContentCleanUp,然後其他過濾器,最後FilterDispatcher)

(3)FilterDispatcher咨詢ActionMapper是否需要調用某個Action來處理這個請求,如果ActionMapper決定調用某個Action,FilterDispatcher則把請求的處理交給ActionProxy。

(4)ActionProxy通過Configuration Manager(struts.xml)詢問架構的配置檔案,找到需要調用的Action類。

(5)ActionProxy建立一個ActionInvocation執行個體,同時ActionInvocation通過代理模式調用Action,但在調用之前,ActionInvocation會根據配置加載Action相關的所有Interceptor(攔截器)

(6)一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的傳回結果result

struts2标簽分類:

1.表單UI标簽

2.非表單UI标簽

3.控制标簽

4.資料标簽

總結常用的注解如下: 

Namespace:指定命名空間

ParentPackage:指定父包

Result:提供了Action結果的映射(一個結果的映射)

Results:“Result”注解清單

ResultPath:指定結果頁面的基路徑

Action:指定Action的通路URL

Actions:“Action”注解清單

ExceptionMapping:指定異常映射(映射一個聲明異常)

ExceptionMappings:一級聲明異常的數組

InterceptorRef:攔截器引用

InterceptorRefs:攔截器引用組

攔截器: 攔截器的執行順序是按照引用攔截器的順序決定的,

攔截器在Struts中的作用:配置了一個過濾器,實作将所有請求傳遞StrutsPrepareAndExecuteFilter類。一旦接受到任意action的請求,該類會建立和初始化一個ActionProxy執行個體,它代理了具體的action,在其中我們可以添加任意攔截器在execute方法執行之前和之後做一些額外的操作,最終會調用該action執行個體的execute方法,為使用者傳回視圖結果字元串,然後系統會根據該視圖結果字元串調取相應的視圖頁面。

自定義攔截器實作類:實作自己的攔截器類隻需要實作Interceptor 接口即可,該接口中有如下(destory、init、intercept)方法

配置和引用攔截器:struts為我們提供API用來針對具體的某個方法配置攔截器。這裡涉及到一個抽象類:MethodFilterInterceptor。該類實際上實作了Interceptor并完成了一些預設實作,

Spring:

Spring IOC:要了解IOC首先要明白依賴倒置原則(Dependency Inversion Principle),就是把原本的高層建築依賴底層建築倒置過來,變成底層建築依賴高層建築。高層建築決定需要什麼,底層去實作這樣的需求,但是高層并不用管底層的是怎麼實作的;而控制反轉(Inversion of Control)就是依賴倒置原則的一種代碼的設計思路;(補充:三種注入方式 :構造器注入、setter方法注入、根據注解注入。)(補充:是指建立對象的控制權的轉移,以前建立對象的主動權和時機是由自己把控的,而現在這種權力轉移到Spring容器中,并由容器根據配置檔案去建立執行個體和管理各個執行個體之間的依賴關系,對象與對象之間松散耦合,也利于功能的複用。DI依賴注入,和控制反轉是同一個概念的不同角度的描述,即 應用程式在運作時依賴IoC容器來動态注入對象需要的外部資源。

(2)最直覺的表達就是,IOC讓對象的建立不用去new了,可以由spring自動生産,使用java的反射機制,根據配置檔案在運作時動态的去建立對象以及管理對象,并調用對象的方法的。

SpringAOP:一般稱為面向切面,作為面向對象的一種補充,用于将那些與業務無關,但卻對多個對象産生影響的公共行為和邏輯,抽取并封裝為一個可重用的子產品,這個子產品被命名為“切面”(Aspect),減少系統中的重複代碼,降低了子產品間的耦合度,同時提高了系統的可維護性。可用于權限認證、日志、事務處理。(補充:關鍵在于 代理模式,AOP代理主要分為靜态代理和動态代理。靜态代理的代表為AspectJ;動态代理則以Spring AOP為代表。

(1)AspectJ是靜态代理的增強,所謂靜态代理,就是AOP架構會在編譯階段生成AOP代理類,是以也稱為編譯時增強,他會在編譯階段将AspectJ(切面)織入到Java位元組碼中,運作的時候就是增強之後的AOP對象。

(2)Spring AOP使用的動态代理,所謂的動态代理就是說AOP架構不會去修改位元組碼,而是每次運作時在記憶體中臨時為方法生成一個AOP對象,這個AOP對象包含了目标對象的全部方法,并且在特定的切點做了增強處理,并回調原對象的方法。)

動态代理的兩種方式:jdk動态代理和cglib動态代理;JDK動态代理隻能對實作了接口的類生成代理,而不能針對類;cglib是針對類實作代理,主要是對指定的類生成一個子類,覆寫其中的方法,因為是繼承,是以該類或方法最好不要聲明稱final,final可以阻止繼承和多态;(補充: ①JDK動态代理隻提供接口的代理,不支援類的代理。核心InvocationHandler接口和Proxy類,如果代理類沒有實作 InvocationHandler 接口,那麼Spring AOP會選擇使用CGLIB來動态代理目标類。CGLIB(Code Generation Library),是一個代碼生成的類庫,可以在運作時動态的生成指定類的一個子類對象,并覆寫其中特定方法并添加增強代碼,進而實作AOP。)

Spring設計模式:

  (1)工廠模式,在各種BeanFactory以及ApplicationContext建立中都用到了;

  (2)模闆模式,也是在各種BeanFactory以及ApplicationContext建立中都用到了;

  (3)代理模式,在AOP實作中用到了JDK的動态代理;

  (4)單例模式,比如建立bean的時候;

  (5)政策模式,第一個地方,加載資源檔案的地方,使用了不同的方法,比如:classPathResource,FileSystemResource,ServletContextResource,UrlResource但他們都有共同的接口Resource;第二個地方就是AOP的實作中,采用了不同的方式,JDK動态代理和CGLIB代理;

注解:

聲明bean的注解@Service 在業務邏輯層使用(service層)

@Repository 在資料通路層使用(dao層)

@Controller 在展現層使用,控制器的聲明(C)

注入bean的注解@Autowired:由Spring提供

@Inject:由JSR-330提供

@Resource:由JSR-250提供

java配置類相關注解@Configuration 聲明目前類為配置類,相當于xml形式的Spring配置(類上)

@Bean 注解在方法上,聲明目前方法的傳回值為一個bean,替代xml中的方式(方法上)

@Configuration 聲明目前類為配置類,其中内部組合了@Component注解,表明這個類是一個bean(類上)

@ComponentScan 用于對Component進行掃描,相當于xml中的context:component-scan/(類上)

Hibernate

是一個持久化的架構,它對JDBC進行了輕量級的封裝。對于源程式來說沒有侵入性。能讓我們通過操作實體關系模型來操作資料庫。大大減輕了sql語句的書寫,事務的處理,查詢結果的管理等資料庫操作。

Configuration接口:Configuration對象用于配置并根啟動Hibernate。

Query接口:Query負責執行各種資料庫查詢。它可以使用HQL語言或SQL語句兩種表達方式。

SessionFactory接口:SessionFactroy接口負責初始化Hibernate。它充當資料存儲源的代理,并負責建立Session對象。

Session接口:Session接口 Session 接口對于Hibernate 開發人員來說是一個最重要的接口。

運作過程:1.通過Configuration().configure();讀取并解析hibernate.cfg.xml配置檔案

2.由hibernate.cfg.xml中的<mappingresource="com/xx/User.hbm.xml"/>讀取并解析映射資訊

3.通過config.buildSessionFactory();//建立SessionFactory

4.sessionFactory.openSession();//打開Sesssion

5.session.beginTransaction();//建立事務Transation

6.persistent operate持久化操作 //一般指Save這個方法

7.session.getTransaction().commit();//送出事務

8.關閉Session

9.關閉SesstionFactory

注解:

@Entity 注解将一個類聲明為實體 Bean,

@Id 注解聲明了該實體Bean的辨別屬性。   

定義表:通過 @Table 為實體Bean指定對應資料庫表,目錄和schema的名字。

@Version 注解用于支援樂觀鎖版本控制。      

@Column 注解将屬性映射到列。   

一對一:使用 @OneToOne 注解可以建立實體Bean之間的一對一關系。

多對一:使用 @ManyToOne 注解定義多對一關系。

一對多 :@OneToMany 注解可定義一對多關聯。一對多關聯可以是雙向SpringMVC

一種基于Java的實作了Web MVC設計模式的請求驅動類型的輕量級Web架構,即使用了MVC架構模式的思想,将web層進行職責解耦,基于請求驅動指的就是使用請求-響應模型,

工作原理

(1)用戶端(浏覽器)發送請求,直接請求到DispatcherServlet。

(2)DispatcherServlet根據請求資訊調用HandlerMapping,解析請求對應的Handler。

(3)解析到對應的Handler後,開始由HandlerAdapter擴充卡處理。

(4)HandlerAdapter會根據Handler來調用真正的處理器開處理請求,并處理相應的業務邏輯。

(5)處理器處理完業務後,會傳回一個ModelAndView對象,Model是傳回的資料對象,View是個邏輯上的View。

(6)ViewResolver會根據邏輯View查找實際的View。

(7)DispaterServlet把傳回的Model傳給View。

(8)通過View傳回給請求者

元件詳解:

1、前端控制器DispatcherServlet(不需要程式員開發)。

  作用:接收請求,響應結果,相當于轉發器,中央處理器。有了DispatcherServlet減少了其它元件之間的耦合度。

2、處理器映射器HandlerMapping(不需要程式員開發)。根據請求的url查找Handler。

3、處理器擴充卡HandlerAdapter(不需要程式員開發)。按照特定規則(HandlerAdapter要求的規則)去執行Handler。

4、處理器Handler(需要程式員開發)注意:編寫Handler時按照HandlerAdapter的要求去做,這樣擴充卡才可以去正确執行Handler

5、視圖解析器ViewResolver(不需要程式員開發)。

  作用:進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)

6、視圖View(需要程式員開發jsp)注意:View是一個接口,實作類支援不同的View類型(jsp、freemarker、pdf…)

轉發與重定向

轉發:在傳回值前面加"forward:",譬如"forward:user.do?name=method4"

重定向:在傳回值前面加"redirect:",譬如"redirect:http://www.baidu.com"

注解:

@RequestMapping請求路徑映射,如果标注在某個controller的類級别上,則表明通路此類路徑下的方法都要加上其配置的路徑;最常用是标注在方法上,表明哪個具體的方法來接受處理某次請求。

@method:指定請求的method類型, GET、POST、PUT、DELETE等;

@params:指定request中必須包含某些參數值是,才讓該方法處理。

@headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。

@consumes:指定處理請求的送出内容類型(Content-Type),例如application/json, text/html。

@RequestParam用于将請求參數區資料映射到功能處理方法的參數上。(value、required、defaultValue)

@PathVariable用于将請求URL中的模闆變量映射到功能處理方法的參數上。

@ModelAttribute可以應用在方法參數上或方法上,他的作用主要是當注解在方法參數上時會将注解的參數對象添加到Model中;

Mybaties

工作原理

mybatis應用程式通過SqlSessionFactoryBuilder從mybatis-config.xml配置檔案(也可以用Java檔案配置的方式,需要添加@Configuration)中建構出SqlSessionFactory(SqlSessionFactory是線程安全的);然後,SqlSessionFactory的執行個體直接開啟一個SqlSession,再通過SqlSession執行個體獲得Mapper對象并運作Mapper映射的SQL語句,完成對資料庫的CRUD和事務送出,之後關閉SqlSession。

接口

1) API接口層:提供給外部使用的接口API,開發人員通過這些本地API來操縱資料庫。接口層一接收到調用請求就會調用資料處理層來完成具體的資料處理。

2)資料處理層:負責具體的SQL查找、SQL解析、SQL執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次資料庫操作。

3)基礎支撐層:負責最基礎的功能支撐,包括連接配接管理、事務管理、配置加載和緩存處理,這些都是共用的東西,将他們抽取出來作為最基礎的元件。為上層的資料處理層提供最基礎的支撐

注解

1>@Insert ::實作新增

2>@Update:實作更新

3>@Delete:實作删除

4>@Select:實作查詢

5>@Result:實作結果集封裝

6>@Results:可以與@Result 一起使用,封裝多個結果集

7>@ResultMap: 實作引用@Results 定義的封裝

8>@One:實作一對一結果集封裝

9>@Many:實作一對多結果集封裝

10>@CacheNamespace:實作注解二級緩存的使用

複雜關系映射的注解說明

1>@Results 注解:代替的是标簽<resultMap>

2>@Resutl 注解:代替了 <id> 标簽和<result> 标簽

3>@One 注解(一對一):代替了<assocation> 标簽,是多表查詢的關鍵,在注解中用來指定子查詢傳回單一對象

4>@Many 注解(多對一):代替了<assocation> 标簽,是多表查詢的關鍵,在注解中用來指定子查詢傳回單一對象

标簽詳解、

1.id屬性作用:辨別映射檔案中的sql,将sql語句封裝到mapper的statement對象中,是以稱為statement的id

      2.parameterType:指定輸入參數類型

      3.#{}:表示一個占位符,${}:表示拼接sql串,将接收到參數的内容不加任何修飾拼接在sql中

       4.#{userId}:其中的userId表示接收的輸入參數,參數名稱就是userId,如果輸入參數是簡單類型,#{}中的參數名可以任意,可以為value或者其他${}:表示拼接sql串,将接收到參數的内容不加任何修飾拼接在sql中,使用${}容易引起sql注入,${value}:接受輸入參數的内容, 如果傳入類型是簡單類型,${}中隻能用value

       5.resultType:指定sql輸出結果的所映射的java對象類型,select指定resultType表示将單條記錄映射成的java對象

            注意:如果使用resultType作為輸出映射,資料庫表字段和實體對象屬性名稱不一緻的将擷取不到值

Struts2和springmvc的本質差別:

       1.springmvc入口是一個servlet前端控制器(DispatcherServlet),struts2入口是一filter過濾器(StrutsPrepareAndExecuteFilter).

        2.struts2通過在action類中定義成員變量接收參數,(屬性驅動和模型驅動),它隻能使用多例模式管理action,springmvc通過在coontroller方法中定義形參接收參數,springmvc可以使用單例模式管理controller.    

        3.springmvc是基于方法開發的,注解開發中使用requestMapping将url和方法進行 映射,如果根據url找到controller類的方法生成一個handler處理器對象(隻包括一個method).

struts2是基于類開發的,每個請求過來建立一個action執行個體,執行個體對象中有若幹個方法.

開發中建議使用springmvc,springmvc方法更類似service業務方法.

        4.struts2采用值棧存儲請求和相應的資料,通過OGNL存取資料,springmvc通過參數綁定期将request請求内容解析,并給方法形參指派.

        5.Struts2是類級别上的攔截,一個類對應一個request上下文,SpringMVC是方法級别的攔截,一個方法對應一個request上下文。而且Struts過濾後是去Struts配置檔案中找Action,而SpringMVC過濾後是去controller中找對應于@RequestMapping注解的url綁定的方法,

         6.也因為攔截器原因,導緻Struts2的action比較亂,因為它要定義屬性來擷取請求中參數的資料,而屬性在一個類的方法間是共享的(方法間不能獨享request、response資料),是以會有點亂。而SpringMVC中請求參數與controller中方法的形參自動配對(在名字相同,或請求參數與形參的屬性名相同,或通過@RequestParam注解指定條件下會自動将請求參數的值賦給形參)方法間可以獨享request、response資料。

         7.SpringMVC內建了Ajax,使用非常友善,隻需一個注解@ResponseBody就可以實作,然後直接傳回響應文本即可,而Struts2攔截器內建了Ajax,在Action中處理時一般必須安裝插件或者自己寫代碼內建進去,使用起來也相對不友善。

mybatis與Hibernater

         1. hibernate是全自動,而mybatis是半自動:hibernate完全可以通過對象關系模型實作對資料庫的操作,擁有完整的JavaBean對象與資料庫的映射結構來自動生成sql。而mybatis僅有基本的字段映射,對象資料以及對象實際關系仍然需要通過手寫sql來實作和管理。

          2. hibernate資料庫移植性遠大于mybatis:hibernate通過它強大的映射結構和hql語言,大大降低了對象與資料庫(oracle、mysql等)的耦合性,而mybatis由于需要手寫sql,是以與資料庫的耦合性直接取決于程式員寫sql的方法,如果sql不具通用性而用了很多某資料庫特性的sql語句的話,移植性也會随之降低很多,成本很高。

           3. hibernate擁有完整的日志系統,mybatis則欠缺一些:hibernate日志系統非常健全,涉及廣泛,包括:sql記錄、關系異常、優化警告、緩存提示、髒資料警告等;而mybatis則除了基本記錄功能外,功能薄弱很多。

           4. sql直接優化上,mybatis要比hibernate友善很多:由于mybatis的sql都是寫在xml裡,是以優化sql比hibernate友善很多。而hibernate的sql很多都是自動生成的,無法直接維護sql;雖有hql,但功能還是不及sql強大,見到報表等變态需求時,hql也歇菜,也就是說hql是有局限的;hibernate雖然也支援原生sql,但開發模式上卻與orm不同,需要轉換思維,是以使用上不是非常友善。總之寫sql的靈活度上hibernate不及mybatis。

SpringBoot

SpringBoot 自動配置主過 @EnableAutoConfiguration、 @Conditional、 @EnableConfigurationProperties 或者 @ConfigurationProperties 等幾個注解來進行自動配置完成的。@EnableAutoConfiguration 開啟自動配置,主要作用就是調用 Spring-Core 包裡的 loadFactoryNames(),将 autoconfig 包裡的已經寫好的自動配置加載進來。@Conditional 條件注解,通過判斷類路徑下有沒有相應配置的 jar 包來确定是否加載和自動配置這個類。@EnableConfigurationProperties 的作用就是,給自動配置提供具體的配置參數,隻需要寫在 application.properties 中,就可以通過映射寫入配置類的 POJO 屬性中。

核心功能

1、獨立運作Spring項目:Spring boot 可以以jar包形式獨立運作,運作一個Spring Boot項目隻需要通過java -jar xx.jar來運作。

2、内嵌servlet容器:Spring Boot可以選擇内嵌Tomcat、jetty或者Undertow,這樣我們無須以war包形式部署項目。

3、提供starter簡化Maven配置:spring提供了一系列的start pom來簡化Maven的依賴加載,例如,當你使用了spring-boot-starter-web,會自動加入如圖5-1所示的依賴包。

4、自動裝配Spring:SpringBoot會根據在類路徑中的jar包,類、為jar包裡面的類自動配置Bean,這樣會極大地減少我們要使用的配置。當然,SpringBoot隻考慮大多數的開發場景,并不是所有的場景,若在實際開發中我們需要配置Bean,而SpringBoot滅有提供支援,則可以自定義自動配置。

5、準生産的應用監控:SpringBoot提供基于http ssh telnet對運作時的項目進行監控。

6、無代碼生産和xml配置

注解:

@SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。其中@ComponentScan讓spring Boot掃描到Configuration類并把它加入到程式上下文。

@Configuration 等同于spring的XML配置檔案;使用Java代碼可以檢查類型安全。

@EnableAutoConfiguration 自動配置。

@ComponentScan 元件掃描,可自動發現和裝配一些Bean。

@Component可配合CommandLineRunner使用,在程式啟動後執行一些基礎任務。

@RestController注解是@Controller和@ResponseBody的合集,表示這是個控制器bean,并且是将函數的傳回值直 接填入HTTP響應體中,是REST風格的控制器。

@Autowired自動導入。

@PathVariable擷取參數。

@JsonBackReference解決嵌套外鍊問題。

@RepositoryRestResourcepublic配合spring-boot-starter-data-rest使用。

SpringCloud

是一套分布式服務治理的架構,既然它是一套服務治理的架構,那麼它本身不會提供具體功能性的操作,更專注于服務之間的通訊、熔斷、監控等。是以就需要很多的元件來支援一套功能。

解決問題

    配置管理(注冊中心Eureka,Dubbo的是Zookeeper)、服務發現、服務注冊、斷路器(非常重要,容錯機制、限流、調用接口失敗如何解決)、路由政策(接口分發那台機器上去)、負載均衡、全局鎖、分布式會話、用戶端調用、接口網關、服務管理系統。

SpringCloud架構

1、外部或者内部的非SpringCloud項目都統一通過API網關(Zuul)來通路内部服務.

2、網關接收到請求後,從注冊中心(Eureka)擷取可用服務

3、由Ribbon進行均衡負載後,分發到後端的具體執行個體

4、微服務之間通過Feign進行通信處理業務

5、Hystrix負責處理服務逾時熔斷

6、Turbine監控服務間的調用和熔斷相關名額

分布式開發五大元件詳解

  • 服務發現——Netflix Eureka:一個RESTful服務,用來定位運作在AWS地區(Region)中的中間層服務。由兩個元件組成:Eureka伺服器和Eureka用戶端。Eureka伺服器用作服務注冊伺服器。Eureka用戶端是一個java用戶端,用來簡化與伺服器的互動、作為輪詢負載均衡器,并提供服務的故障切換支援。Netflix在其生産環境中使用的是另外的用戶端,它提供基于流量、資源使用率以及出錯狀态的權重負載均衡。
  • 客服端負載均衡——Netflix Ribbon:Ribbon,主要提供客戶側的軟體負載均衡算法。

Ribbon用戶端元件提供一系列完善的配置選項,比如連接配接逾時、重試、重試算法等。Ribbon内置可插拔、可定制的負載均衡元件。下面是用到的一些負載均衡政策:簡單輪詢負載均衡、權重響應時間負載均衡、區域感覺輪詢負載均衡、随機負載均衡

Ribbon中還包括以下功能:

易于與服務發現元件(比如Netflix的Eureka)內建使用Archaius完成運作時配置

使用JMX暴露運維名額,使用Servo釋出

  • 斷路器——Netflix Hystrix:斷路器可以防止一個應用程式多次試圖執行一個操作,即很可能失敗,允許它繼續而不等待故障恢複或者浪費 CPU 周期,而它确定該故障是持久的。斷路器模式也使應用程式能夠檢測故障是否已經解決。如果問題似乎已經得到糾正​​,應用程式可以嘗試調用操作。
  • 服務網關——Netflix Zuul:類似nginx,反向代理的功能,不過netflix自己增加了一些配合其他元件的特性。
  • 分布式配置——Spring Cloud Config

注解:@SuppressWarnings(忽視某些警告)

@Async &&  @EnableAsync

作用:@EnableAsync注解的意思是可以異步執行,就是開啟多線程的意思。可以标注在方法、類上。為了讓@Async注解能夠生效,需要在Spring Boot的主程式中配置@EnableAsync,@Async所修飾的函數不要定義為static類型,這樣異步調用不會生效

@EnableEurekaServer:啟動一個服務注冊中心提供給其他應用進行對話

@EnableZuulProxy:開啟網關;

@FeignClient:發現服務

@EnableFeignClients:啟用feign進行遠端調用

@EnableDiscoveryClient:啟用服務注冊與發現

@EnableCircuitBreaker:啟動斷路器

@EnableEurekaClient:啟用服務注冊與發現

@EnableDiscoveryClient基于spring-cloud-commons; @EnableEurekaClient基于spring-cloud-netflix;其實用更簡單的話來說,就是如果選用的注冊中心是eureka,那麼就推薦@EnableEurekaClient,如果是其他的注冊中心,那麼推薦使用@EnableDiscoveryClient。

繼續閱讀