使用Spring的註釋和反射讓程式碼更精簡

banq發表於2018-12-23

Java總是因為臃腫而受到批評。但是有一些方法可以最小化所有臃腫重複程式碼。這個Spring beans教程向您展示瞭如何編寫更高效的應用程式。

假設我們有50個不同的StateFormParsers用於解析每個傳入表單獲得所在的州名稱,每個、表單都有一組不同的欄位。此外,每個表單中表達州名稱的格式可能是文字或HTML,因此我們需要100個不同的解析器(50個狀態乘以兩種不同的格式)。我們絕對可以找到程式碼共享的地方,但我們仍需要為進入系統的每個表單找到正確的解析器。
現在,當我們收到表單時,我們希望找到一種優雅的方法來從控制反轉(IoC)容器中檢索正確的實現。我們只想要傳入資料告訴我們狀態和格式就可以了。

我們如何快速簡單地找到我們需要的Spring bean?

註釋類的定義
首先建立一個自定義註釋,可以將其放在每個實現類上,使它們成為可用的一種Spring bean。甚至可能在ComponentScan中使用新的註釋,以便這個註釋將放在每一個類上,並使每個實現類都成為一個Spring bean,甚至不必在其上新增@Component型別的註釋了。

需要建立的註釋如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface StateFormParser {
 
   String state();
   String format() default "text";
}


這樣可以在每個解析器上使用此註釋,然後設定狀態和格式值。以下是支援州名稱是HTML格式的解析器示例,CA代表California :

@StateFormParser(state="CA", format="html")
public class CaliforniaParser extends StateFormParserBaseClass {
}


下一步是在Spring元件掃描配置中,將它新增到componentScan配置的includeFilters屬性中。使用@ComponentScan時,它看起來像這樣:

@ComponentScan(basePackages = ["com.serverside],includeFilters = [
  @ComponentScan.Filter(type=FilterType.ANNOTATION, value=StateFormParser.class),
  @ComponentScan.Filter(type=FilterType.ANNOTATION, value=Repository.class),
  @ComponentScan.Filter(type=FilterType.ANNOTATION, value=Service.class),                
  @ComponentScan.Filter(type=FilterType.ANNOTATION, value=Controller.class)
  ]
)

Spring IoC容器建立其ApplicationContex/BeanFactory時,解析器bean將存在上下文中。

但是如何找回它們?

Spring在ListableBeanFactory中有一個擴充套件BeanFactory的方法,你可以在ApplicationContext中找到它。

Map<String, Object> getBeansWithAnnotation(
Class<? extends Annotation> annotationType) 
throws BeansException;


我們用這個方法可以獲得所有使用我們自定義註釋@StateFormParser標註的所有bean,如果每個bean還實現相同的類StateFormParserBaseClass,我們也可以執行autowiring。

@Autowired Map<String, StateFormParserBaseClass> formParserMap;

map 的String是bean名稱,值是bean例項。

下面程式碼是迴圈Map尋找出每個Bean,以發現我們需要使用的解析器Bean:

private StateFormParserBaseClass getFormParser(String state, String format) {
  StateFormParserBaseClass beanFormParser = null;
 
  for (StateFormParserBaseClass formParser: formParserMap.values()) {
    StateFormParser stateFormParser = formParser.getClass().getAnnotation(StateFormParser.class);
    if (stateFormParser.state().equals(state) && stateFormParser.format().equals(format)) {
    beanFormParser = formParser;
    }
  }
    return beanFormParser
}


還有許多其他方法可以檢索正確的解析器bean,但是使用這個Spring bean教程,您可以使用註釋和簡單的反射方法或Spring應用程式方法呼叫來簡化問題。
 

相關文章