1. 程式人生 > >Spring——使用cglib更新長生命週期中引用的短生命週期bean

Spring——使用cglib更新長生命週期中引用的短生命週期bean

在長生命週期的bean引用短生命週期bean時,會有一個問題。 比如singleton 類依賴了prototype類,容器會在singleton 類初始化時,就根據依賴關係將prototype類注入。以後的每一次呼叫singleton bean都是同一個物件,裡面的prototype bean也是最初注入的那個,容器再也不會為singleton bean產生新的prototype bean。
我們可以通過在短生命週期的bean定義中加入<aop:scoped-proxy/>輕鬆解決這個問題。

但是,有些業務情況要求在增加新的bean時,不允許改動以前的bean定義和舊的程式碼。簡單的說:被呼叫者(短生命週期bean)不允許修改,只能修改呼叫者(新增的長生命週期bean),所以這篇就講講如何利用Lookup達到我們的要求。

Lookup方法的工作機制是使用cglib在產生位元組碼這個階段生成一個代理類,因此我們先要在工程中引入cglib元件。

程式程式碼如下:

介面:

package twm.spring.lookup;
public interface UserSession {
    Object getInstance();
}

介面的實現類:

package twm.spring.lookup;
public class UserSessionImpl implements UserSession{
    @Override
    public Object getInstance() {
        return this;
    }
}

業務類ServiceBean依賴UserSession:
因為setUserSession只是宣告,並沒有實現,所以是個抽象方法。宣告這個抽象方法是為了讓Lookup注入代理物件的。
當然也可以不宣告為抽象方法(並不是強制要求),不過最終Lookup會覆蓋原方法裡的實現內容。

package twm.spring.lookup;
public abstract class ServiceBean {
    UserSession userSession;
    //原來的setter注入不要了
    //public void setUserSession(UserSession userSession) {
    //  this.userSession = userSession;
    //}
    public Object Perform(){
        this.userSession=setUserSession();
        return this.userSession.getInstance();
    }
    //抽象方法,由lookup-method注入具體bean
    abstract UserSession setUserSession();
}

beans.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:c="http://www.springframework.org/schema/c" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

<bean id="usession" class="twm.spring.lookup.UserSessionImpl" scope="prototype">
</bean> 

<bean id="servicebean" class="twm.spring.lookup.ServiceBean">
    <!-- <property name="UserSession" ref="usession"/> -->
    <!-- name是類中返回代理物件的方法名,bean是lookup-method要代理的物件 -->
    <lookup-method name="setUserSession" bean="usession"/>
</bean> 
</beans>

呼叫程式碼:

ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
ServiceBean us=ctx.getBean("servicebean",ServiceBean.class);
System.out.println(us.Perform());
System.out.println(us.Perform());

執行輸出:

[email protected] 
[email protected]

打印出的兩個usession物件的地址不一樣,說明我們實現了每次呼叫都能獲得新的短生命週期的物件。
<lookup-method>標籤中的name屬性就是servicebean Bean中獲取UserSession例項的方法,即:setUserSession()方法;bean屬性是要注入的bean物件,這裡是usession。

相關推薦

Spring——使用cglib更新生命週期引用生命週期bean

在長生命週期的bean引用短生命週期bean時,會有一個問題。 比如singleton 類依賴了prototype類,容器會在singleton 類初始化時,就根據依賴關係將prototype類注入。以後的每一次呼叫singleton bean都是同一個物件,裡

解決gradle更新後導致app引用不到module下的jar包問題

    博主最近拿到一個二次開發的專案。公司以前這個專案是外包出去的,外包做的,大家也知道外包怎麼工作的,四個字形容就是快速開發,那麼就有些問題,很多東西框架比較落伍過時,拿到手改掉網路框架,不支援ip的反向代理於是從底層換掉網路框架,哎,難為我這個菜雞了,然後我發現grad

總結Spring框架擴充套件點(二)bean生命週期的擴充套件點(持續更新...)

面向業務開發的時候,程式設計師需要明白業務的邏輯,並設計程式碼結構。而在進行中介軟體開發的時候,則需要明白框架的邏輯,進行開發。 所以要開發提供給spring的中介軟體,需要知道spring中有哪些擴充套件點,好在對應的地方插入我們的功能。 1. Spring容器初始化b

Spring Bean生命週期各方法的執行順序

Spring 容器中的 Bean 是有生命週期的,Spring 允許在 Bean 在初始化完成後以及 Bean 銷燬前執行特定的操作,常用的設定方式有以下十種: 通過實現 InitializingBean 介面來定製初始化之後的操作方法; 通過實現DisposableBean 介面來定

springbaen的生命週期,及生命週期的作用

最近在看spring原始碼,所以總結下spring的生命週期和各個階段的作用。 spring的生命週期概括起來主要如下: 例項化 屬性注入 ioc注入 實現了BeanNameAware 則執行setBeanName方法  實現了BeanFactoryAw

Spring生命週期bean注入生命週期bean問題

Spring中Bean的生命週期有singleton prototype request session global session application,預設的生命週期是singleton在容器

Spring AOP在Bean生命週期的呼叫時機

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

Vue生命週期的 mounted

mounted() { }      //真實dom渲染完了,可以操作dom了 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

spring boot 2.x html引用css和js失效

在application.properties中配置了static的預設路徑 我的static目錄結構是這樣的 index.html中這樣引用css或者js檔案,用到了th標籤 html使用th標籤需要先匯入   以上這樣配置好了之後發現網頁的c

【Django】Django請求的生命週期

Django的請求生命週期是指當用戶在瀏覽器上輸入url到使用者看到網頁的這個時間段內,Django後臺所發生的事情 1. 當用戶在瀏覽器中輸入url時,瀏覽器會生成請求頭和請求體發給服務端 請求頭和請求體中會包含瀏覽器的動作(action),這個動作通常為get或者post,體現在url之中。 2. u

java類的生命週期-強引用,弱引用,虛引用,軟引用

1.強引用 package com.cap3; public class Test1 { static Object strongRefence=new Object(); public static void main(String[] args) {

Asp.Net Core服務的生命週期選項區別和用法

  在做一個小的Demo中,在一個介面上兩次呼叫檢視元件,並且在檢視元件中都呼叫了資料庫查詢,結果發現,一直報錯,將兩個檢視元件的呼叫分離,單獨進行,卻又是正常的,尋找一番,發現是配置依賴注入服務時,對於服務的生命週期沒有配置得當導致,特此做一次實驗來認識三者之間(甚至是四者之間的用法及區別)。 一、服務

const 引用延長生命週期

const可以延長方法返回回來的臨時變數的生存週期。 主要是兩種情況 1:返回的是臨時變數的引用 2:為匿名臨時變數建立引用 前者是錯誤的,返回的那一刻就被delete #include<iostream> class A { public: A()

Spring系列學習之Spring Cloud Skipper發現應用程式並管理其生命週期

英文原文:https://cloud.spring.io/spring-cloud-skipper/ 目錄 Spring Cloud Skipper 概覽 特性 入門 歷史 釋出版本 相關專案 Spring Cloud Skipper Skipper是一種

普通類引用spring 容器管理的bean

今天遇到一個問題,在webservice介面中去注入spring管理的類的時候出現了空指標的問題,但是呢,這個webservice類並沒有交給spring去做統一管理,那麼要怎麼注入到spring的b

軟體生命週期的攻防博弈

大資料的時代,軟體幾乎深入到人們生活的各個方面,某種意義上可以說,現在是軟體的時代。這個大時代下,攻與防,充斥在軟體生命週期的各個階段,時時處處在演繹。 1. 資訊保安的攻防 網路購物,網上金融,網

使用Lifecycle管理Tomcat元件的生命週期

大型軟體和汽車製造工廠一樣,元件繁多,關係複雜,相互協同完成了汽車的生產過程。軟體中的Object就像是工廠中component一樣。 下面來看看相關的類和介面: abstract class LifecycleBase implements Lifecycle:可以看到元件生命週期的一些引數。 abs

軟體測試技術---在軟體生命週期測試的實施

1.軟體的生命週期 同任何事物一樣,軟體也有一個孕育,誕生,成長,成熟,衰亡的過程,這個過程被稱為軟體生命週期 大致可分為以下幾個階段: 制定規劃->系統與與軟體需求分析->軟體設計->程式設計與單元測試->整合與系統測試->執行與維護 每個

技術雜記,軟體生命週期的攻防博弈

經常抓包分析的小夥伴們可能注意到了一個現象,有時候你獲取的HTTP包有點彆扭——HTTP包的狀態行或者訊息報頭有冗餘(欄位等)、HTTP訊息報頭中的一些關鍵詞大小寫不規整(比如“Date”寫為“daT

oracle更新字元型資料的純數字為定(不足左邊補0)

之前需求文件的錯造成了原本3位數的數字不是定長的,後來發現需求文件把需求記錯了,這個欄位中的純數字必須是3位的.這個欄位目前已有數千行資料,有字母組合,字母數字組合及純數字,位數都不是定長的. 所以只能寫個指令碼來更新,但oracle中是沒有判斷是否是數字或字母型別的字元型資