亚洲乱码中文字幕综合视频|亚洲国产综合精品二区|国产在线精品一区二区不卡顿|中文乱码在线播放亚洲

<object id="6gxjn"><tt id="6gxjn"></tt></object>
<span id="6gxjn"></span>
  • <address id="6gxjn"><ul id="6gxjn"><strike id="6gxjn"></strike></ul></address>
  • <label id="6gxjn"></label>

    <style id="6gxjn"></style>

    <address id="6gxjn"></address>
    <pre id="6gxjn"></pre>
    Spring源碼解析 Bean的生命周期-MyBatis

    Spring源碼解析 Bean的生命周期-MyBatis

    2020-04-18    09'03''

    主播: 橙汁兒橙汁兒。

    185 2

    介紹:
    1.Spring Bean 的生命周期 (1)實例化 ApplicationContext 對象 (2)掃描類、解析類 (3)生成 BeanDefinition 對象,并把解析到的信息:如 類名、父類、類型:原型 prototype 還是 單例 Singleton;有無延遲加載等信息作為對象的屬性。 (4)把 BeanDefiniation put 到 map 中。 (5)Spring 會遍歷這個 map,先驗證,返回 String 類型的 BeanName (6)推斷構造方法,獲取所有的 Constructor,根據合適的構造方法通過反射構建對象,并把對象封裝成 BeanWrapper 包裝類對象。 (7)看是否允許循環(huán)依賴,默認是單例模式,是允許循環(huán)依賴的,會把對象封裝成 SingletonFactory,放置在 SingletonFactories 中。這是二級緩存,本質是個 HashMap,key 是 String 類型,value 是 ObjectFactory 類型。 (8)populateBean 進行屬性注入 (9)回調 Aware 接口 (10)執(zhí)行初始化生命周期方法 invokeInitMethod,順序是 注解、接口、XML (11)是否需要代理,需要的話會完成 AOP (12)經過以上步驟后會把對象放置到一級緩存 SingletonObjects 中,這是個 ConcurrentHashMap,key 是 String 類型,value 是 Object ,放置的是經過完整生命周期的 Bean 以上是單例模式,如果是原型或者延遲加載,只有獲取對象時才會創(chuàng)建對象,而容器關閉時單例對象會銷毀,而對于原型,一個類不只一個對象,所以不會銷毀。 2.Spring 是如何解決循環(huán)依賴的 先說說什么是循環(huán)依賴:比如 a 中有屬性 b,并通過 setB 方法設置;同理,b 中有屬性 a,并通過 setA 設置,這樣就出現(xiàn)了循環(huán)依賴。默認 單例模式是允許循壞依賴的,而原型模式下是會報錯的。 假設先走 A 的生命周期,是允許循環(huán)依賴的,就會在二級緩存 SingltonFactories 中放置 A 的工廠對象,而且還有一個 Set 是放置“正在創(chuàng)建中”的對象的 beanName 集合,A 的 beanName 會被放置到這個集合中,到了要進行屬性注入的時候,會調用 getBean(B) 嘗試獲取 B 對象,先去一級緩存 SingletonObjects 中嘗試獲取,是獲取不到的,接下來會判斷 B 是否在創(chuàng)建中,到 Set 中獲取,也獲取不到,這時會去創(chuàng)建 B ,走 B 的生命周期,那相同地,B 也會在二級緩存中生成工廠對象、在 Set 中放置 B 的 beanName,到了 B 需要注入屬性時,調用 getBean(A) 嘗試獲取對象 A,先到一級緩存中,獲取不到,這時會判斷 A 是否正在創(chuàng)建中,在 Set 中是可以獲取到 A 的 beanName 的,就會先去三級緩存 EarlySingletonObjects 中,獲取不到,再去二級緩存 SingletonFactories 中,可以獲取到 A 的工廠,通過 getObject() 方法就可以通過工廠獲取到 A 對象,而且會把工廠從二級緩存中 remove() 移除,并把對象放置到三級緩存中,那么獲取到 A 對象就可以作為屬性給 B 注入了,B繼續(xù)向下走生命周期,直到放置到 單例池 SingltonObjects 中,就生成了完整的 bean B,然后回退,把它作為 屬性注入給 A,A再繼續(xù)向下走生命周期,這樣 A、B 就分別走完了完整的生命周期并進行了相互的屬性注入。 3.Bean 三級緩存的作用 一級:SingletonObjects 放置經過完整生命周期的對象 二級:SingletonFactories 用于解決循環(huán)依賴,提供工廠,方便代理 三級:EalrySingletonObjects 用于提前暴露對象,如復雜的循環(huán)依賴 a、b、c,如果 b 注入屬性 a,會從 二級緩存獲取到 a,接著移到三級緩存中,接下來 c 也需要注入屬性 a 時,就會先從三級緩存中獲取,避免重復生產。 4.@Resource 和 @Autowired @Resource 是 JDK 的 注解,而 @Autowired 是 Spring 框架中的注解。 @Autowired 默認情況下是按照 類型 type 裝配 bean 的,而 @Resource 默認是按照 名稱 name 裝配,如果沒有匹配的 name ,才會按照 類型 type 進行裝配。 處理這兩個注解的后置處理器不同,@Resource 是 CommonAnnotationBeanPostProcessors 處理的。 @Autowired 是AutoWiredAnnotationBeanPostProcessers 處理的。 5.Mybatis SqlSeesionFactoryBuilder.build() 內部是使用 parse() 解析每一個子節(jié)點,比如會把 Configuration 節(jié)點解析成 configuration 類,這是個全局配置類,對于 mappers 節(jié)點,有 mapper 或者 package 兩種子節(jié)點,會去相應的邏輯中處理。 mapper 有三種屬性:resource、url、class ,這三個中只能指定一個;package 中有 interface、class、xml,有個 isInterface() 方法可以獲取到接口,然后判斷是否加載過資源,如果沒有加載過就會使用 loadResource(),這里的資源是指和接口在同一個包下的 xml,build() 方法會返回一個 DefaultSqlSessinFactory。再使用 sqlsessionFactory.openSession() 會開啟一個會話,每個 SqlSession 會對應一個數(shù)據庫,然后使用 sqlsession.getMapper() ,是通過 MapperProxyFactory 的 newInstance() 產生一個 MapperProxy實例,它是實現(xiàn)了 InvocationHandler 接口的,有實現(xiàn) invoke() 方法,在這個方法中完成了 SQL 語句的執(zhí)行。 對于不同類型的語句 select、update、delete、insert 會生成對應的 mapperStatement 對象,對于參數(shù),如果是一個參數(shù),生成 Object 類型的對象,如果是多個參數(shù),生成一個 map,比如說 String 類型的參數(shù),就有 StringTypeHandler() ,會執(zhí)行 setString() 把參數(shù)設置進去,比如說 查詢就會執(zhí)行 doQuery() 方法,會通過 Configuration 類獲取數(shù)據庫的信息,會生成 prepareStatement,本質上也是 JDBC 操作。 6.#{} 和 ${} 的區(qū)別 MyBatis 會把 SQL 語句作為 SQLSource 處理的,#{} 會作為靜態(tài)的 SQLSource,解析時會用 ? 占位符來代替 #{},執(zhí)行的時候將 ? 占位符用參數(shù)變量替換掉。 而 只要帶 $,就會作為 動態(tài)的 SQLSource 進行處理,解析時不會用占位符,而是保持原先的 SQL 語句,執(zhí)行的時候才用參數(shù)變量替換,這樣容易出現(xiàn) SQL 注入的問題。
    上一期: Java基礎 集合類
    下一期: Java NIO-Tomcat NIO