Java項目筆記之知識點總結02


不點藍字,咱們哪來故事?



Spring

Spring 是一個輕量級的 IoC / DI  和 AOP 容器的開源框架,致力於構建輕量級的 JavaEE 應用,簡化應用開發。前端

IoC 和 DI 思想
  1. IoCjava

    將本來在程序中對象的建立權,交由 spring的IoC 容器來管理,強調建立對象mysql

  2. DIweb

    指 Spring 建立對象的過程當中,將對象依賴屬性(常量,對象,集合)經過配置設值給該對象。強調設置對象的屬性值。面試


Spring項目的建立:
  1. 建立Maven項目,添加依賴和插件;org.springframeworkspring

  2. 須要經過配置文件applicationContext.xml告訴spring來管理哪些對象;sql

    BeanFactory:表示 Spring IoC 容器 — 生產 bean 對象的工廠,負責配置,建立和管理 bean。數據庫

    • 文件是Spring Bean Configuration File,文件名通常爲:applicationContext.xml;express

    • 在配置文件中完成<bean>標籤的配置:經過id和class屬性來告訴Spring容器來管理這個對象。apache

    • 從容器中獲取這個對象:找到這個配置文件,底層經過反射建立對象,並保存在容器中進行管理;

    • 注入屬性:<property>標籤來指定對象的屬性名的屬性值;

  3. 測試:經過BeanFactory來獲取被管理的bean對象;

    getBean的方法:

    類型 變量名 = beanFactory.getBean("配置文件中的name",配置文件的類型.class);


Spring IoC 管理 bean 的原理

  1. 經過 Resource 對象加載配置文件;

  2. 解析配置文件,解析 bean 元素,id 做爲 bean 的名字,class 用於反射獲得 bean 的實例,注意:此時,bean 類必須存在一個無參數構造器(和訪問權限無關);

  3. 調用 getBean 方法的時候,從容器中返回對象實例。


<import resource="文件路徑"/>

applicationContext.xml文件中,項目規模變大時,<bean>元素太多,分類分解成多個xml文件,經過<import resource="文件路徑"/>的方式將這些xml文件引入便可。

<import resource="classpath:cn/wolfcode/day1/_02_hello/hello.xml"/>

SpringText

Spring 容器在管理測試代碼,節省性能的開銷。添加spring-test的依賴。

@Runwith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

@Autowired


IoC 容器
Spring IoC 容器(Container)
  • Spring IoC 容器(Container)

    • 應用中,通常不使用 BeanFactory,而推薦使用 ApplicationContext(應用上下文),它繼承自BeanFactory,在啓動Spring的時候就會把全部的bean都建立好了;

    • 在字段上貼@Autowired註解,能夠直接獲取到容器中的bean。

bean的做用域:
  • singleton:單例 ,在 Spring IoC 容器中僅存在一個 bean 實例 (缺省默認的 scope);

  • prototype:多例 ,每次從容器中調用 Bean 時,都返回一個新的實例,即每次調用 getBean() 時 ,至關於執行 new Xxx():不會在容器啓動時建立對象。

注意:

只有正常關閉容器,纔會執行 bean 的配置的 destroy-method 方法。

bean 的 scope 爲 prototype 的,那麼容器只負責建立和初始化,它並不會被 Spring 容器管理(不須要存起來),交給用戶本身處理。即 bean 做用域爲 prototype 的即便配置了 destroy-method 也不會被調用。

DI
注入方式:
  1. setter方法注入:

    setter 方法注入又叫屬性注入,但其類必須提供對應 setter 方法。

    <property name="對象屬性名稱" value="須要注入的值"/>
  2. bean注入:

    注入 bean,就是把一個 bean(非基本數據類型),經過 setter 方法設置給另外一個 bean;

    <property name="對象屬性名稱" ref="被注入對象的bean的id" />
  3. 注入集合:

    就是把一個集合類型的數據,經過 setter 方法設置給一個 bean;




配置Druid數據庫鏈接池

使用Spring以前,須要經過DruidDataSource對象來設置鏈接數據庫的四要素才能鏈接。太麻煩。添加依賴:druid、mysql-connector-java

如今只須要在applicationContext.xml 文件中配置便可:

配置以後:經過注入DruidDataSource對象 . getConnection()便可得到鏈接對象。


property-placeholder

配置db.properties,在applicationContext.xml 文件中引入db跑配置文件。

location屬性爲配置文件的路徑;db中配置前綴jdbc.,防止從環境中去獲取屬性的值。

Autowired 和 Qualifier 註解

共同點:

  1. 可讓 Spring 自動的把屬性或字段須要的對象找出來,並注入到屬性上或字段上。

  2. 能夠貼在字段或者 setter 方法上面。

  3. 能夠同時注入多個對象。

不一樣點:

  • Autowired 註解尋找 bean 的方式:(先按類型在按名字)

  • Resource 註解尋找 bean 的方式:(先按名字再按類型)


IoC註解:

簡化不少的bean的配置:

  • @Repository 用於標註數據訪問組件,即 DAO 組件。

  • @Service 用於標註業務層組件

  • @Controller 用於標註控制層組件(如 Struts2 中的 Action,SpringMVC 的 Controller)。

  • @Component 泛指組件,當組件很差歸類的時候,咱們可使用這個註解進行標註。標註除上其餘組件。

須要配置IoC DI註解解析器:讓IoC註解或者DI註解起做用,發現某類貼有@Component註解,Spring就會建立這個類的對象存在Spring容器中

貼了註解以後,還須要配置IoC組件掃描器:

 <!-- 配置 IoC DI 註解解析器 讓Spring幫咱們建立業務對象 -->
 <context:component-scan base-package="cn.wolfcode.xxx"/>


靜態代理
  1. 代理對象徹底包含真實對象,客戶端使用的都是代理對象的方法,和真實對象沒有直接關係;

  2. 代理模式的職責:把不是真實對象該作的事情從真實對象上撇開——職責分離。

缺點:代理類本身實現,項目大,代理類多。


動態代理

動態代理類是在程序運行期間由 JVM 經過反射等機制動態的生成的,因此不存在代理類的字節碼文件,動態生成字節碼對象,代理對象和真實對象的關係是在程序運行時期才肯定的。

實現選擇:

  1. 針對有接口:使用 JDK 動態代理

  2. 針對無接口:使用 CGLIB 或 Javassist 組件。


JDK 動態代理

前提

委託類(真實類),必須實現接口。

java.lang.reflect.Proxy 類

 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler hanlder)

方法職責:爲指定類加載器、一組接口及調用處理器生成動態代理類實例

 參數:  
  loader :類加載器,通常傳遞真實對象的類加載器
  interfaces:代理類須要實現的接口
  handler:代理執行處理器,說人話就是生成代理對象幫你要作什麼 返回:建立的代理對象
     返回:建立的代理對象                


java.lang.reflect.InvocationHandler 接口

public Object invoke(Object proxy, Method method, Object[] args)

方法職責:負責集中處理動態代理類上的全部方法調用,讓使用者自定義作什麼事情,對原來方法加強。

參數:
proxy :生成的代理對象
method:當前調用的真實方法對象
args :當前調用方法的實參
返回:真實方法的返回結果

操做步驟

  1. 定義封裝事務操做的一個模擬類。

  2. 實現 InvocationHandler 接口,實現 invoke 方法,實現加強操做。

  3. 在 Spring 配置文件中配置 InvocationHandler  實現類、事務操做模擬類、真實對象,讓其幫咱們建立對象組裝依賴。

  4. 在單元測試類中注入 InvocationHandlerbean,在測試方法中手動使用 Proxy 建立代理對象,調用代理對象的方法。

調用流程:

CGLIB 動態代理和原理

JDK 動態代理要求真實類必須實現接口。而 CGLIB 與 JDK 動態代理不一樣,真實類不用實現接口,代理類會繼承真實類。

org.springframework.cglib.proxy.Enhancer//相似 JDK 中 Proxy,用來生成代理類建立代理對象的。
org.springframework.cglib.proxy.InvocationHandler//相似 JDK 中InvocationHandler,讓使用者自定義作什麼事情,對原來方法加強。

操做步驟

  1. 修改 TransactionHandler 實現 org.springframework.cglib.proxy.InvocationHandler 接口,其餘不變。

  2. 修改單元測試類中的測試方法,改用 Enhancer 來生成代理類建立代理對象的。

調用流程:


動態代理的選用:

若真實類實現了接口,優先選用 JDK 動態代理。(真實類與代理類是共同實現一個接口)

若真實類沒有實現任何接口,使用 Javassit 和 CGLIB 動態代理。(代理類是繼承自真實類的)

動態代理問題:對多個 service 對象加強配置太多,還有要手動建立代理對象,在使用時不是面向接口,還要編寫 InvocationHandler 接口的實現類。


AOP 思想

AOP(Aspect Oriented Programming),是面向切面編程的技術。

  • Joinpoint:鏈接點,通常指須要被加強的方法。where:去哪裏作加強。

  • Pointcut:切入點,哪些包中的哪些類中的哪些方法,可認爲是鏈接點的集合。where:去哪些地方作加強。

  • Advice:加強,當攔截到 Joinpoint 以後,在方法執行的什麼時機(when)作什麼樣(what)的加強。

  • Aspect:切面,Pointcut + Advice,去哪些地方 + 在何時 + 作什麼加強

  • Target:被代理的目標對象。

  • Weaving:織入,把 Advice 加到 Target 上以後,建立出 Proxy 對象的過程。

  • Proxy:一個類被 AOP 織入加強後,產生的代理類。


AOP 實現及 Pointcut 表達式

AspectJ 是一個面向切面的框架

AspectJ 切入點語法(表示在哪些包下的哪些類的哪些方法上作切入加強)

execution(* cn.wolfcode.wms.service.*.*(..))
execution(* cn.wolfcode.wms.service.*Service.*(..))
execution(* cn.wolfcode..service.*Service.*(..))


添加依賴:aspectjweaver

配置

<!-- 配置須要加的功能(加強)WHAT -->
<bean id="tx" class="cn.wolfcode.tx.MyTranansationManager"/>

<!-- 配置真實類型的對象 -->
<bean id="employeeService" class="cn.wolfcode.service.impl.EmployeeServiceImpl"/>

<!-- AOP的配置 -->
<aop:config proxy-target-class="true">
<!-- 切面 -->
<aop:aspect ref="tx">
<!-- 定義切入點:WHERE -->
<aop:pointcut expression="execution(* cn.wolfcode.service.impl.*ServiceImpl.*(..))" id="txPointcut"/>
<!-- 切入表達式中的方法,在方法執行以前調用tx.begin() -->
<aop:before method="begin" pointcut-ref="txPointcut"/>

<!-- 切入表達式中的方法,在方法正常執行完後調用tx.commit() -->
<aop:after-returning method="commit" pointcut-ref="txPointcut"/>

<!-- 切入表達式中的方法,在方法執行過程當中出現異常時調用tx.rollback() -->
<aop:after-throwing method="rollback" pointcut-ref="txPointcut"/>
</aop:aspect>
</aop:config>


使用 CGLIB

作以下配置便可:



轉帳功能集成:
  1. 使用框架,在別人的基礎上開發,提升效率;

  2. 集成 MyBatis 和業務層,即業務對象、 Mapper 對象等都交由 Spring 容器管理,使用 Spring IoC 和 DI 來完成對象建立及其屬性注入,後面再使用 AOP 來配置事務。

依賴及插件:
  1. MyBatis框架所須要的依賴:

    • mybatis

      • mybatis-spring

  2. 數據庫驅動:

    • mysql-connector-java :SQL鏈接數據庫(做用域:runtime)

  3. 數據庫鏈接池:Druid

    • druid

  4. 日誌打印:

    • slf4j-log4j12

  5. Spring框架:

    • spring-test:測試(做用域:test)

    • Spring-jdbc:鏈接數據庫

    • aspectjweaver :AOP

    • spring-webmvc :MVC層

  6. web項目共用的:

    • lombok (做用域:provided)

    • junit(做用域:test)

    • javax.servlet-api (做用域:provided)

  7. 頁面標籤:支持 JSTL

    • taglibs-standard-spec

    • taglibs-standard-impl

插件:

  1. 編譯插件:maven-compiler-plugin

    <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
    <source>1.8</source><!-- 更新項目(Maven | Update Project)以後,會修改項目的編譯版本 -->
    <target>1.8</target><!-- 更新項目以後,會修改項目的運行版本 -->
    <encoding>utf-8</encoding><!-- 更新項目以後,Java 編譯器讀取你的文件用的編碼 -->
    </configuration>
    /plugin>
  2. 服務器maven項目插件:org.apache.tomcat.maven

    <plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <configuration>
    <port>80</port><!-- 端口 -->
    <path>/</path> <!-- 上下路徑 -->
    <uriEncoding>UTF-8</uriEncoding> <!-- 針對 GET 方式亂碼處理 -->
    </configuration>
    </plugin>


配置SqlSessionFactory

使用MyBatis須要建立SqlSessionFactory對象,交給Spring處理。

配置:

配置 Mapper 的代理對象

Mapper接口的實現類讓Spring來代理。管理需提供 Mapper 接口(接口中多參數使用@Param註解)和 Mapper XML 文件。


配置業務層對象

編寫業務接口和實現類:

配置業務對象:

測試:


註解方式整合 MyBatis
一、配置 Mapper 接口掃描器

以前配置多個Mapper 接口代理對象是比較麻煩的,使用 Mapper 接口掃描器能夠批量生成 Mapper 接口代理對象並註冊到 Spring 容器中。

二、使用註解方式配置業務對象

在業務類上貼 IoC 註解和 DI 註解:

在 applicationContext.xml 配置文件配置第三方解析程序:

配置總成:

  <!-- 配置事務管理器 -->
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <!-- 配置數據源 -->
  <property name="dataSource" ref="dataSource"/>
  </bean>
 
  <!-- 配置 IoC DI 註解解析器 讓Spring幫咱們建立業務對象 -->
  <context:component-scan base-package="cn.wolfcode.ssm.service.impl"/>
 
  <!--
  配置時機(相似環繞加強:任什麼時候候都能起做用),並關聯上面上事務管理器
  針對不一樣方法能夠區分配置
 
  切入點表達式切到的方法,在方法執行以前調用 transactionManager.getTransaction()
  切入點表達式切到的方法,在方法執行正常執行完調用 transactionManager.commit()
  切入點表達式切到的方法,在方法執行拋出異常時調用 transactionManager.rollback()
  -->
  <!--CRUD通用事務配置 WHEN-->
  <tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
             <!--Servlet中查詢的方法-->
  <tx:method name="get*" read-only="true"/>
  <tx:method name="list*" read-only="true"/>
  <tx:method name="query*" read-only="true"/>
  <tx:method name="count*" read-only="true"/>
  <tx:method name="select*" read-only="true"/>
             <!--Servlet中非查詢的方法-->
  <tx:method name="*"/>
  </tx:attributes>
  </tx:advice>
 
  <!-- 配置AOP -->
  <aop:config>
  <!-- 定義 WHERE -->
  <aop:pointcut expression="execution(* cn.wolfcode.ssm.service.impl.*ServiceImpl.*(..))"
  id="txPointcut"/>
         <!-- WHERE WHEN -->
  <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
  </aop:config>
 
 
 
  <!-- 引入 db.properties:其中保存了鏈接數據庫的四要素 -->
  <context:property-placeholder location="classpath:db.properties"/>
 
  <!-- 配置 DataSource 對象:數據源     鏈接數據庫的四要素 -->
  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
  <property name="driverClassName" value="${jdbc.driverClassName}"/>
  <property name="url" value="${jdbc.url}"/>
  <property name="username" value="${jdbc.username}"/>
  <property name="password" value="${jdbc.password}"/>
  </bean>
 
  <!-- 配置 SqlSessionFactory 對象 -->
  <bean id="sqlSessionFactory"
  class="org.mybatis.spring.SqlSessionFactoryBean">
  <!--
  關聯 MyBatis :主配置文件
  主配置文件 配置能夠不配置什麼內容,可是約束和根元素必定要保留
  若要配置:只須要配置延遲加載、二級緩存
  -->
  <property name="configLocation" value="classpath:mybatis-config.xml"/>
  <!-- 配置別名 -->
  <property name="typeAliasesPackage" value="cn.wolfcode.ssm.domain"/>
  <!-- 配置數據源:鏈接數據庫 -->
  <property name="dataSource" ref="dataSource"/>
  <!-- 關聯Mapper文件:和Mapper接口編譯後位置在一塊兒 ,因此能夠不配置 -->
  <!-- <property name="mapperLocations" value="classpath:cn/wolfcode/ssm/mapper/*Mapper.xml"/> -->
  </bean>
 
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="cn.wolfcode.ssm.mapper"/>
  </bean>
 </beans>




Spring MVC

MVC框架,它解決Web開發中常見的問題(參數接收、文件上傳、表單驗證、國際化等),與Spring無縫集成。

Servlet JavaBean JSP,減小耦合,提升可維護性。


前端控制器思想:

Front Controller模式要求在WEB應用系統的前端設置一個入口控制器,是用來提供一個集中的請求處理機制,全部的請求都被髮往控制器統一處理,而後把請求分發給各自相應的處理程序,通常用來作一個共同的處理。由於前端控制器集中處理請求的能力,提升了可重用性和可拓展性。

Spring將處理請求的對象稱之爲處理器/控制器( Controller)。使用MVC框架必須在web.xml中配置前端控制器,通常的,要麼是要 Filter,要麼是 Servlet。Spring MVC 是基於 Servlet實現的


添加依賴和插件:

spring-webmvcjavax.servlet-api;服務器插件、編譯插件;


配置前端控制器:org.springframework.web.servlet.DispatcherServlet

編寫處理器類:貼註解@Controller  方法的註解@RequestMapping("/xxx")

編寫 Spring MVC 配置文件

處理器Controller 的響應處理

Controller 方法能夠有多個不一樣類型的參數,以及一個多種類型的返回結果。涉及到經過控制器的方法設計來完成處理請求處理和響應數處理。

響應處理關注的有兩方面:

  • Controller 方法的返回類型;

  • Controller 共享數據到視圖頁面。


  1. 處理方法返回 ModelAndView:Controller方法中定義 ModelAndView 對象並返回,對象中設置模型數據並指定視圖。

    消除視圖前綴和後綴:配置這個,那麼方法最後要找的視圖就是:前綴+邏輯視圖名+後綴名。

  2. 處理方法返回 String

    返回 String 類型和共享數據(使用普遍),此時和 Model 參數組合使用。

    下面返回值爲 String,此時物理視圖路徑爲:前綴+邏輯視圖名+後綴。

    • 請求轉發:加上forward: 前綴方式,表示請求轉發,至關於 request.getRequestDispatcher().forward(request,response),轉發後瀏覽器地址欄不變,共享以前請求中的數據。

    • 重定向:加上redirect: 前綴方式,表示重定向,至關於 response.sendRedirect(),重定向後瀏覽器地址欄變爲重定向後的地址,不共享以前請求的數據。

  3. 使用處理方法的形參來接收請求參數

    • 請求參數名和 Controller方法的形參同名:能夠直接接收

    • 請求參數名和 Controller方法的形參不一樣名:使用 @RequestParam 註解貼在形參上,設置對應的請求參數名稱。

    • 請求參數不是必須(用戶能夠不傳該參數):可使用 @RequestParam 的 required 爲 false。


亂碼處理
  1. get 方式傳遞中文參數亂碼問題:在pom.xml文件的Tomcat插件中設置

  2. post 方法傳遞中文亂問題:直接使用 Spring MVC 內置的編碼過濾器來處理。

處理複合類型請求參數
  1. 數組類型參數:多個同類型的請求參數,可直接用數組來接收;

  2. JavaBean 自定義類型參數:注意:請求參數必須和對象的屬性同名

    @ModelAttribute 註解:@ModelAttribute("xx"):能夠貼在方法和形參上,

    形參前提是自定義類型,會存到模型裏,可在視圖中獲取到

    • 若沒貼這個註解,則經過類型首字母小寫做爲 key 獲取;

    • 若貼了這個註解,能夠自定義 key,再經過這個 key 獲取。

日期類型處理

前臺日後臺傳參轉換爲 Date 類型:在對象字段或 Controller 形參貼上 @DateTimeFormat

在 JSP 中顯示 Date 類型的數據,此時須要使用 fmt 標籤。添加依賴才能支持 JSTL

taglibs-standard-spectaglibs-standard-impl



Spring MVC 文件上傳

依賴:commons-fileupload

上傳表單注意請求的類型必須是:multipart/form-data,且是 POST。

配置上傳解析器注意上傳解析器這個 bean 名稱是固定的,必須爲 multipartResolver。

上傳控制器:接收上傳文件,並把上傳的文件拷貝項目的根路徑下指定目錄,文件名隨機(防止文件覆蓋)。

核心組件分析

一、核心組件

  1. 前端控制器 DispatcherServlet

不須要咱們開發,由框架提供,須要在 web.xml 中配置。做用:接受請求,處理響應結果,轉發器,中央處理器。

  1. 處理器映射器 HandlerMapping

不須要咱們開發,由框架提供。做用,更具請求的 URL 找到對應的 Handler。

  1. 處理器適配器 HandlerAdapter

不要咱們開發,由框架提供。做用:調用處理器(Handler / Controller)的方法。

  1. 處理器 Handler(又名 Controller),後端控制器

須要咱們開發,必須按照 HandlerAdapter 的規範去開發。做用:接收用戶請求數據,調用業務方法處理請求。

  1. 視圖解析器 ViewResolver

不須要咱們開發,有框架或者第三方提供。做用:視圖解析,把邏輯視圖名稱解析成真正的物理視圖。支持多種視圖技術 Velocity、FreeMarker、JSP 等。

  1. 視圖

須要咱們開發。做用:把數據展示給用戶。


開發步驟:
  1. 配置前端控制器

  2. 配置處理器映射器、處理適配器、視圖解析器(用默認的可不配置)。

  3. 須要開發(結合需求):

  • 先開發 Contoller,再配置。

  • 開發 JSP。


執行流程分析

一、圖示流程

二、文字描述

  1. 用戶發送出請求到前端控制器 DispatcherServlet。

  2. DispatcherServlet 收到請求調用 HandlerMapping(處理器映射器)。

  3. HandlerMapping 找到具體的處理器(經過 XML 或註解配置),生成處理器對象及處理器攔截器(如有),再一塊兒返回給 DispatcherServlet。

  4. DispatcherServlet 調用 HandlerAdapter(處理器適配器)。

  5. HandlerAdapter 通過適配調用具體的處理器的某個方法(Handler/Controller)。

  6. Controller 執行完成返回 ModelAndView 對象。

  7. HandlerAdapter 將 Controller 返回的 ModelAndView 再返回給 DispatcherServlet。

  8. DispatcherServlet 將 ModelAndView 傳給 ViewReslover(視圖解析器)。

  9. ViewReslover 解析後返回具體 View(視圖)。

  10. DispatcherServlet 根據 View 進行渲染視圖(即將模型數據填充至視圖中)。

  11. DispatcherServlet 響應用戶。

解耦,責任分離,可替換實現。看源碼分析執行流程。




java學途

只分享有用的Java技術資料 

掃描二維碼關注公衆號

 


筆記|學習資料|面試筆試題|經驗分享 

若有任何需求或問題歡迎騷擾。微信號:JL2020aini

或掃描下方二維碼添加小編微信

 




小夥砸,歡迎再看分享給其餘小夥伴!共同進步!




本文分享自微信公衆號 - java學途(javaxty)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索