1. 程式人生 > >spring事務傳播、動態代理、ioc、aop、bean生命週期

spring事務傳播、動態代理、ioc、aop、bean生命週期

Spring動態代理的兩種方式
總結
一個典型的動態代理建立物件過程可分為以下四個步驟:
1、通過實現InvocationHandler介面建立自己的呼叫處理器 IvocationHandler handler = new InvocationHandlerImpl(...);
2、通過為Proxy類指定ClassLoader物件和一組interface建立動態代理類
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});
3、通過反射機制獲取動態代理類的建構函式,其引數型別是呼叫處理器介面型別
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4、通過建構函式建立代理類例項,此時需將呼叫處理器物件作為引數被傳入
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
為了簡化物件建立過程,Proxy類中的newProxyInstance方法封裝了2~4,只需兩步即可完成代理物件的建立。
生成的ProxySubject繼承Proxy類實現Subject介面,實現的Subject的方法實際呼叫處理器的invoke方法,而invoke方法利用反射呼叫的是被代理物件的的方法(Object result=method.invoke(proxied,args))

cglib動態代理是生成被代理類的子類,並覆蓋其中方法進行增強。

  • 事務巢狀:兩個事務方法之間相互呼叫。同一個類中的方法呼叫事務方法不生效,是因為事務切面。
    通過spring注入的類是代理類,代理類會有事務切面,但是原來的類只是普通的類,呼叫它的方法就只是簡單執行它的方法而已。

  • spring預設情況下會對uncheck異常(執行時異常)進行事務回滾;checked不回滾。

  • 改變預設規則
    rollbackFor=Exception.class
    notRollbackFor=

    1. required:如果存在一個事務,則支援當前事務。如果沒有則開啟一個新的事務。預設
    2. supports:如果存在一個事務,支援當前事務。如果沒有事務非事務的執行
    3. mandatory:如果存在一個事務,支援當前事務。如果沒有一個活動的事務,則丟擲異常

    不支援當前事務:

    1. requires_new:總是開啟一個新的事務。如果存在則將這個事務掛起。子事務不會直接影響到父事務的提交和回滾。
    2. not_supported:總是非事務的執行,並掛起任何存在的事務。
    3. never:總是非事務的執行,如果存在一個活動事務,則丟擲異常。

    巢狀

    1. nested:如果一個活動的事務存在,則執行在一個巢狀的事務中,如果不存在則新建事務。
      子事務是父事務的一部分,由父事務統一提交。父事務回滾,子事務也會回滾。子事務回滾,會回到一個savepoint點。

ioc:控制反轉,也是依賴注入。將物件交給容器控制來注入物件。
配置好bean後,由容器給我們注入bean
用反射實現。
通過解析xml檔案或java配置,獲取到beanid和class屬性內容,利用反射,通過class.forName獲得class物件再來例項化物件,然後將它放進spring的bean容器中。
通過反射例項化物件,存入到Spring的bean容器中。


當一個類需要另一個類時,從容器中獲取到對應的bean物件,獲取類的setter方法的Method類,setter呼叫invoke方法執行,注入之前拿到的bean物件。

面向切面程式設計,在一個地方定義通用功能,可以通過宣告的方式定義這個功能在類的哪裡應用,而無需修改受影響的類。可將系統功能與核心業務邏輯相分離。(安全、日誌、事務等)
通知:執行的工作
切點:連線點
切面:通知+切點
只支援方法級別的連線點(切點)
把切面應用到目標物件時動態建立一個代理類,攔截被通知方法的呼叫,執行切面邏輯。
動態代理主要是實現InvocationHandler,並且將目標物件注入到Handler中,利用反射機制來執行目標物件的方法。

proxy.newProxyInstance(物件的類載入器, 目標物件的介面, InvocationHandler);

InvocationHandler中的invoke,由代理類呼叫

public Object invoke(Object proxy 代理類, Method method 呼叫的方法, Object[] args 引數)
呼叫目標物件的方法
method.invoke(this.target, args);

bean的作用域
單例(singleton)
原型(prototype)
會話(session)代理,延遲注入
請求(resquest)

springmvc請求順序
dispatcherServlet-->HandlerMapping
............................-->Controller-->Model/viewname
............................-->viewResolver-->view-->返回響應
所有請求通過dispatcherservlet前端控制器,dispatcherservlet查詢一個或多個mappinghandler處理器對映,決定將請求發給哪個controller;
控制器處理完後產生資訊model,將它打包並標示用於渲染輸出的檢視名。接下來將請求和資訊傳送回dispatcherservlet;
前端控制器使用viewresovler檢視解析器將邏輯檢視名匹配給一個特定的檢視實現;
檢視將model渲染輸出,通過響應物件傳遞給客戶端。

  1. 啟動springmvc
    <mvc:annotation-driven>註解啟用
    @Configuration 配置類
    @EnableWebMvc 啟用springmvc
    @ComponentScan("包") 開啟元件掃描
    ViewResolver{}

  2. 控制器
    @Controller 類
    @RequestMapping(value="/",method=RequestMethod.GET) 方法或類級別,value能接收一個String型別的陣列

  3. model
    方法引數,返回string或其他值,會自動放進模型中,響應給 string連結或者返回json或請求路徑(邏輯檢視由請求路徑推出)

  4. 查詢引數
    @RequestParam(value="max",defaultValue="3") long max,url上的查詢引數

  5. 路徑變數
    @RequestMapping(value="/{max}")
    @PathVariable(value="max") long max, 通過路徑引數接受輸入,資源通過url標識

  6. 重定向:"redirect:" flash屬性通過會話中轉
    請求轉發:"forward:"

  7. 校驗表單:@NotNull、@Null、@Size等
    應用:@Valid Lei lei,Error errors){ errors.hasErrors()}

  8. web.xml中配置dispatcherservlet

  9. 異常
    特定的spring異常會自動對映為指定的http狀態碼
    @ExceptionHandler(XXException.class) 方法,同一類中的異常由這個方法處理

  10. @ResponseBody 方法,將返回的物件轉化為json
    @RequestBody 引數,將Json轉化為java物件
    @RestController 類,@[email protected]

查詢字串(名稱/值對)是在 GET 請求的 URL 中傳送的:
GET 請求可被快取
GET 請求保留在瀏覽器歷史記錄中
GET 請求可被收藏為書籤
GET 請求不應在處理敏感資料時使用
GET 請求有長度限制
GET 請求只應當用於取回資料

查詢字串(名稱/值對)是在 POST 請求的 HTTP 訊息主體中傳送的:
POST 請求不會被快取
POST 請求不會保留在瀏覽器歷史記錄中
POST 不能被收藏為書籤
POST 請求對資料長度沒有要求

冪等性??

spring 容器
負責建立物件,裝配它們,配置並管理它們的整個生命週期。即物件由spring容器建立和裝配,並存在容器中。

  • bean工廠,是最簡單的容器,提供基本的DI支援。
  • 應用上下文,基於beanFactory構建,提供應用框架級別的服務,例如從屬性檔案解析文字資訊以及釋出應用事件給感興趣的事件監聽者。

spring bean的生命週期
正確理解它非常重要,因為或許需要利用spring提供的擴充套件點來自定義bean的建立過程。
Spring預設例項化Bean的情況下,採用的是lazy機制,換言之,如果不通過getBean()方法(BeanFactory或者ApplicationContext的方法)獲取Bean的話,那麼為了節省記憶體將不例項話Bean,只有在Bean被呼叫的時候才例項化他們。

  • 例項化
    解析xml配置檔案或java配置類,獲取到beanid和class屬性內容,利用反射,通過class.forName獲得class物件再例項化物件。
  • 填充屬性
    當屬性是另一個類是,從容器中獲取到對應的bean引用,獲取以例項化物件的setter方法的Method類,setter呼叫invoke方法執行,注入bean引用。(屬性注入。構造器注入在例項化部分)
  • 呼叫BeanNameAware的setBeanName()方法
    如果bean實現了BeanNameAware介面,會呼叫setBeanName,將bean的名字傳給bean自己,
  • 呼叫BeanFactoryAware的setBeanFactory()方法
    、、、、、傳入beanFactory容器,
  • 呼叫ApplicationContextAware的setApplicationContext()方法
    (用DefaultListableBeanFactory實現的容器例項化物件時不會呼叫ApplicationContextAware的方法)
    、、、、、傳入ApplicationContext容器
  • 呼叫BeanPostProcessor的預初始化方法,即postProcessorBeforeInitialization()方法
  • 呼叫InitializingBean的afterPropertiesSet()方法
    如果bean使用init-method聲明瞭初始化方法,也會呼叫
    - 呼叫自定義的初始化方法
  • 呼叫BeanPostProcessor的初始化後方法,即postProcessorAfterInitialization()方法
  • 可以使用bean了,將一直駐留在應用上下文中,直到該應用上下文被銷燬
    容器關閉
  • 呼叫DisposableBean的destory()方法
    如果使用destroy-method聲明瞭銷燬方法,該也會被呼叫。
    - 呼叫自定義的銷燬方法

BeanPostProcessor如果有bean實現了這個介面,那麼其他bean會呼叫這個bean實現的方法。

相關推薦

Spring事務Transactional和動態代理(一)-JDK代理實現

系列文章索引: 1. [Spring事務Transactional和動態代理(一)-JDK代理實現](http://www.itrensheng.com/archives/spring_transaction_jdk_proxy) 2. [Spring事務Transactional和動態代理(二)-cglib

Spring事務Transactional和動態代理(二)-cglib動態代理

系列文章索引: 1. [Spring事務Transactional和動態代理(一)-JDK代理實現](http://www.itrensheng.com/archives/spring_transaction_jdk_proxy) 2. [Spring事務Transactional和動態代理(二)-cglib

Spring事務Transactional和動態代理(三)-事務失效的場景

系列文章索引: 1. [Spring事務Transactional和動態代理(一)-JDK代理實現](http://www.itrensheng.com/archives/spring_transaction_jdk_proxy) 2. [Spring事務Transactional和動態代理(二)-cglib

Spring AOPBean生命週期中的呼叫時機

之前有寫了一個生命週期的例子,直接拿來用,在每個生命週期方法中呼叫print方法。見上一篇 加上AOP的程式碼 package com.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.a

spring事務傳播動態代理iocaopbean生命週期

Spring動態代理的兩種方式 總結 一個典型的動態代理建立物件過程可分為以下四個步驟: 1、通過實現InvocationHandler介面建立自己的呼叫處理器 IvocationHandler handler = new InvocationHandlerImpl(...); 2、

什麽是事務事務特性事務隔離級別spring事務傳播特性

ons pri table 產生 serializa support enc 不一致 修改 1.什麽是事務: 事務是程序中一系列嚴密的操作,所有操作執行必須成功完成,否則在每個操作所做的更改將會被撤銷,這也是事務的原子性(要麽成功,要麽失敗)。 2.事務特性: 事務特性分為

事務傳播無效,required_new無效,動態代理spring事務傳播留下的坑

事務的傳播級別 七種傳播級別 propagation_requierd:如果當前沒有事務,就新建一個事務,如果已存在一個事務中,加入到這個事務中,這是最常見的選擇。(預設) propagation_supports:支援當前事務,如果沒有當前事務,就以

Spring事務傳播屬性介紹(二).mandatorynot_supportedneversupports

Required、Required_New傳播屬性分析傳送門:https://www.cnblogs.com/lvbinbin2yujie/p/10259897.html Nested傳播屬性分析傳送門:https://www.cnblogs.com/lvbinbin2yujie/p/10260066.ht

SpringAOP靜態代理動態代理

1. AOP 1.1 AOP簡介 AOP Aspect Oriented Programing 面向切面程式設計 AOP採取橫向抽取機制,取代了傳統縱向繼承體系重複性程式碼(效能監視、事務管理、安全檢查、快取) Spring中的Aop是純J

java 代理模式(靜態代理動態代理Cglib代理) 轉載

cas 代理人 缺點 intercept 必須 lan itcast 技術 有時 Java的三種代理模式 1.代理模式 代理(Proxy)是一種設計模式,提供了對目標對象另外的訪問方式;即通過代理對象訪問目標對象.這樣做的好處是:可以在目標對象實現的基礎上,增強額外的功能操

03動態代理--JDK動態代理和CGLib動態代理的組合實例

listen -- offer pri eth err imp instance music package com.offer.note.Java基礎.動態代理.CGLib引入增強; public interface Browser { void visitI

靜態代理動態代理

== getclass 切面 接口 tor 7月 第一個 proxy 字節碼   代理模式最大的優勢就是能夠解耦,在spring中也是廣泛使用。spring中一個重要的特性就是aop,aop是個啥東西呢?其實很簡單,比如現在有個業務方法,那這個業務方法很重要,涉及到非常重要

動態代理

1、理解代理模式 假設讀者您目前就職於一家軟體公司,擔任軟體工程師角色。客戶帶著需求來到你們公司,顯然客戶不會直接和你進行交流,而是去找商務,此時客戶會認為商務就代表公司。此時商務就可以看成代理物件,而您,偉大的軟體工程師,就可以看成一個真實的物件。 商務這個角色存在的意義就在於商務可以進行談判。比如客戶

靜態代理動態代理Cglib代理全面梳理

1.1   代理(Proxy)是一種設計模式, 提供了對目標物件另外的訪問方式;即通過代理訪問目標物件。 這樣好處: 可以在目標物件實現的基礎上,增強額外的功能操作。(擴充套件目標物件的功能)。 舉例:明星(鄧紫棋)<-----經紀人<-------

java基礎-代理(靜態代理動態代理cglib代理

代理(Proxy)是一種設計模式,提供了對目標物件另外的訪問方式;即通過代理物件訪問目標物件.這樣做的好處是:可以在目標物件實現的基礎上,增強額外的功能操作,即擴充套件目標物件的功能. 這裡使用到程式設計中的一個思想:不要隨意去修改別人已經寫好的程式碼或者方法,如果需改修改

struts.xml配置詳解(名稱空間約束動態代理

1、package 元素: 1.1 作用:方便分模組化開發 1.2 屬性: name:必須有。唯一。標識一個包, 好有一定的含義。 extends:繼承。一般要求必須繼承struts-default的包。不繼承該包,將無法使用struts2提供的一些核心功能。stru

帶你用例項學習代理模式:靜態代理動態代理(JDKCGlib)以及區別和優缺點

Spring AOP的核心技術就是動態代理,所以小編學習並整理了代理模式的材料,供大家一起學習。 1、代理模式滿足的三個必要條件: 兩個角色:執行者、被代理物件 這個過程必須要做,但是自己不能做或者不想做,交給專業的人(媒婆) 執行者必須拿到被代理物件的引用(需要知道你要什

Mybatis進階學習筆記——動態代理方式開發Dao介面Dao層(推薦第二種)

1.原始方法開發Dao  Dao介面 1 package cn.sm1234.dao; 2 3 import java.util.List; 4 5 import cn.sm1234.domain.Customer; 6 7 public interface Custo

JDBC/InvocationHandler動態代理實現資料庫連線池資料來源

Java的JDBC程式設計中,資料庫的連線和關閉是十分耗費資源的。當對資料庫的訪問不是很頻繁時,可以在每次訪問資料庫時建立一個連線,用完之後關閉。但是,對於一個複雜的資料庫應用,頻繁的建立、關閉連線,會極大的減低系統性能,造成瓶頸。所以可以使用資料庫連線池來達到

靜態代理動態代理,以及動態代理的呼叫說明

提前說說 專案中涉及到的程式碼我都會上傳到碼雲(gitee)或者github上,提供給大家下載參考,文中就以最簡單的方式說明執行過程。原始碼的地址在文末哦! 代理模式 代理模式分為靜態代理和動態代理兩種方式,靜態代理是在開發的時候就寫好代理的過