我剛剛發現今天這個老問題,它最近編輯後。
你想要的是基於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]
您可以包括這裏的整個程序?很難理解沒有看到主要方法的情況。它也看起來像你的示例程序輸出不符合你的示例代碼。 –
另一種評論。您的問題標題具有誤導性。 pertypewithin不會形成單例方面。只有在方面聲明中沒有每個子句時纔會創建單例方面。如果我正確理解你的問題,你應該問「AspectJ中的方面實例化與pertypewithin」。 –