[英]Spring AOP: How to pass argument from called method to advice method?
[英]How to pass Spring context as a method argument?
我需要有關Spring的幫助(SpringBoot 1.3.2.RELEASE,Spring 4.3.11.RELEASE)。 用例很特殊,需要解釋。
我有一個Spring應用程序來管理客戶發送的請求。 為了處理這些請求,我們需要使用帶有@Autowired批注聲明的服務。 很經典。
最近,我們決定處理來自其他國家的新型請求。 關鍵是面對不同情況和不同類型的請求,我們決定實施策略模式。 ->根據請求的類型,我們執行在運行時選擇的策略。 每個策略都包含在一個具體的類中,並且所有策略共享相同的接口。
所以,我有:
我現在有 :
問題在於,在加載Spring上下文之后,將無法再使用@Autowired注釋。 我想在我的具體策略類中使用的所有服務都無法再由@Autowired調用,並保持為NULL。
通過將需要的服務作為參數傳遞給具體的策略類,我找到了一種解決方法,但是作為一種參數,我必須傳遞的服務數量因一種策略而異。
我想我應該通過整個Spring上下文,但是我不知道該怎么做。 而且我也不知道如何從上下文訪問所有帶注釋的服務。
PS:我不顯示代碼行,因為我認為實際上沒有必要。 如果您認為代碼更明確,我會發送一些。
提前感謝。
您應該聲明一個工廠來映射依賴關系,而不是將服務聲明為bean,而是在將服務的具體實例返回到注入器之前,它將檢查請求。 在這里看看:
https://grokonez.com/spring-framework/spring-core/use-spring-factory-method-create-spring-bean
您可以使用下面的類來靜態獲取應用程序上下文和Bean
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
@Service
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
大家很快回答我。 首先,對於您最近對所有評論的回答如此,我必須道歉。 上一次沖刺是一個很大的負擔,而新的沖刺並不好^^
我的需要是在Spring上下文創建和加載應用程序的所有部分之后,在對象上創建對象。 作為策略模式的一部分,我必須在運行時實例化一個類,具體取決於必須處理的請求文件中的某些值。 此類需要使用@Autowired
批注聲明的許多服務,但是所有自動裝配的對象仍為' null
',因為在加載上下文之后調用了該服務。
這是我首先要使用的代碼。 沒有春天就可以了。
Function<Document, IStrategy> func = doc -> {
String strategyToApply = "";
IStrategy strategy = null;
switch(doc.getPlace()) {
case "Paris":
strategyToApply = "strategies_classes.ProcessParis";
break;
case "New York":
strategyToApply = "strategies_classes.ProcessNewYork";
break;
}
case "Roma":
...
try {
**Class<?> classToUse = Class.forName(strategyToApply);
strategy = (IStrategy) classToUse.newInstance();**
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return strategy;
};
Consumer<Document> consumerStrategy = doc -> {
IStrategy strategy = func.apply(doc);
strategy.bookRequest(doc);
};
documents.stream()
.forEach(consumerStrategy);
我終於找到了魔法對象。 當Spring對象的生命周期不符合我們自己的概念時,這是一個很好的解決方法。
要使用它,您只需使用@Autowired進行聲明:
@Autowired
private AutowireCapableBeanFactory autowireBeanFactory;
注意,AutowireCapableBeanFactory是一個Spring對象,您無需在其他任何地方聲明!
然后,要使用它,很簡單(我設計了一種全新的服務,與您在上面看到的完全不同,但是它的作用相同):
public <T> T getStrategyToUse(Entity bookingCtr, Funder funder, StrategyEnum strategy) throws FunctionalException {
String strategyToApply = null;
strategyToApply = strategyDao.getClassToApply(bookingCtr, funder, strategy);
Class<?> classToUse;
try {
classToUse = Class.forName(strategyToApply);
T strat = (T) **autowireBeanFactory.getBean**(classToUse);
return (T) strat;
} catch (ClassNotFoundException e) {
LOGGER.error("The indicated Strategy class was not found", e);
}
return null;
}
在運行時加載時,將立即實例化所選的類,並且其所有自動裝配對象將不再為null。
我希望這將有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.