2013-01-01 104 views
0

我想要做一個單身模式使用AspectJ和條款pertypewithin在AspectJ中的方面實例與pertypewithin

這是爲了教育目的,以充分理解條款,我已經做了這個使用其他技術,但我不能讓它工作,因爲我希望。

package resourceManager; 



//For every Type that extends resource 
public aspect ResourcePool pertypewithin(resource+) { 
    //The resource  
    public Object cached; 



Object around(Object instance): execution(*.new(..))&&!within(resource)&&this(instance){ 
    if(cached==null) 
     { 
     proceed(instance); 
     cached=instance; 
     } 


    System.out.println(instance+" "+ cached); 

    return cached; 
}  




} 

我的問題是,在最後我回到緩存,但在我的主要功能的新對象將持有實例的值。在方面內部它的行爲應該是這樣的:第一次我實例化一個資源,緩存和實例將保持相同的值,第二次,他們會有所不同。

instance: [email protected] cached: [email protected] 
instance: [email protected] cached: [email protected] 

但是,當我打印2個新的對象,出現這種情況:

[email protected] 
[email protected] 
+0

您可以包括這裏的整個程序?很難理解沒有看到主要方法的情況。它也看起來像你的示例程序輸出不符合你的示例代碼。 –

+0

另一種評論。您的問題標題具有誤導性。 pertypewithin不會形成單例方面。只有在方面聲明中沒有每個子句時纔會創建單例方面。如果我正確理解你的問題,你應該問「AspectJ中的方面實例化與pertypewithin」。 –

回答

0

我剛剛發現今天這個老問題,它最近編輯後。

你想要的是基於pertypewithin的緩存解決方案。雖然這個想法很好,但有一個技術問題:您不能從around() : execution(*.new(..))建議中返回對象,因爲所討論的對象尚未完全實例化,並且環繞建議隱含返回void。嘗試自己並將建議返回類型更改爲void,並且不返回任何內容。它的作品 - 驚喜,驚喜! ;-)

那麼你可以做什麼呢?改爲使用around() : call(*.new(..))來操作構造函數調用的結果。您甚至可以通過不從那裏調用proceed()來完全跳過對象創建。

有幾種方法可以利用它來使你的資源對象緩存單身人士。但是因爲你特別要求了一個pertypewithin用例,所以我將選擇一個涉及這種類型的方面實例化的解決方案。這裏的缺點是你需要結合兩個方面才能達到預期的結果。

樣品資源類:

package de.scrum_master.resource; 

public class Foo {} 
package de.scrum_master.resource; 

public class Bar {} 

驅動應用程序中創建的每個資源類型的多個實例:

package de.scrum_master.app; 

import de.scrum_master.resource.Bar; 
import de.scrum_master.resource.Foo; 

public class Application { 
    public static void main(String[] args) { 
     System.out.println(new Foo()); 
     System.out.println(new Foo()); 
     System.out.println(new Bar()); 
     System.out.println(new Bar()); 
    } 
} 

改性資源池方面的版本:

package de.scrum_master.resourceManager; 

public aspect ResourcePool pertypewithin(de.scrum_master.resource..*) { 
    private Object cached; 

    after(Object instance) : execution(*.new(..)) && this(instance) { 
     // Not necessary because SingletonAspect only proceeds for 'cache == null' 
     //if (cached != null) return; 
     cached = instance; 
     System.out.println("Cached instance = " + cached); 
    } 

    public Object getCachedInstance() { 
     return cached; 
    } 
} 

看點跳過對象創建對象並返回緩存的對象:

package de.scrum_master.resourceManager; 

public aspect SingletonAspect { 
    Object around() : call(de.scrum_master.resource..*.new(..)) { 
     Object cached = ResourcePool 
      .aspectOf(thisJoinPointStaticPart.getSignature().getDeclaringType()) 
      .getCachedInstance(); 
     return cached == null ? proceed() : cached; 
    } 
} 

控制檯日誌:

Cached instance = [email protected] 
[email protected] 
[email protected] 
Cached instance = [email protected] 
[email protected] 
[email protected]