這樣,在後的將要在前,在前的將要在後了。
Bean 符合特定規範的 Class,例如 Bean 可以被序列化。(不懂?簡單的說,就是產生的物件(instance,object)可以被轉成文字串,以文字串傳遞,又可以從文字串復活為物件(instance,object),這可以算是一種馴化,就是能被序列化的Bean,是"比較聽話的咖啡豆")
@Component 是特殊的 @Bean,而@Service,@Repository以及@Controller 是特殊的 @Component,“特殊的”以程式的說法就是 “繼承自”,即 @Component 繼承自 @Bean,或是說 @Bean 衍生 @Component。即
@Bean -> @Comonent -> (@Service, @Repository, @Controller)
IOC 是一種設計的概念。例如:我們要成立一個翻譯小組,有(張三,李四,王二麻子),這是固定的,在程式一開始設計就決定的,必須先有張三,李四,王二麻子,然後能成立翻譯小組;現在我們介紹另一個作法是,假設這個翻譯小組,其實是要懂俄文,懂英文,懂西班牙文的,因此這個翻譯小組變成 (懂俄文的人,懂英文的人,懂西班牙文的人),然後就算這個翻譯小組就成立了,另一方面,每個入會的人再去領牌子,例如:懂俄文、懂英文、懂西班牙文(至於相同內容的牌子是否只有一個,就是另外一個問題,因此也會衍生一些變化),然後,小組要出動時,再從牌子去選人,這樣是不是就倒過來了?先有了翻譯小組,人再入會。IOC另外有一個名稱就是 DI,就是要出動時,再 "注入" (injection) 實際的人,而不是一開始就決定的。接著我們比較一下,編程的差異:
// 子類別(person)被父類別(group)用到,先定義
class person { … }
// 父類別(group)會用到子類別(person)
class group {
person1 = new person(…);
person2 = new person(…);
person3 = new person(…);
…
}
@Bean 放在函數(成員)之前(其實,前後無關,他們是不同的檔案,也可以稱作平行,就是彼此無關),例如:
@Bean(name= {"desc","Parameter_Type"})
@Scope(value = "prototype")
public static Description getInstance(String name) {
return new Description(name);
}
呼叫的方式,必須先取得 context, 這有點講究,
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Description.class);
Description desc = (Description) context.getBean("desc","mattrew");
((AnnotationConfigApplicationContext) context).close();
第一行 AnnotationConfigApplicationConext() 也可以改成三行
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Description.class);
context.reflash();
重新創建,當然可以,但 ApplicationContext 系統會自動創建,創建後不會關閉,因此也可以直接當作類別的 data member 來使用,例如:
@Autowired
private ApplicationContext context;
還有一點必須要注意,在class Description 中必須包含有一個沒有參數的 Constructor. (可以用Source > Generate Constructors from Superclass 自動編程)。
透過司普令符(Spring Boot)更簡化,@Component 放在 Class 宣告之前(符要貼對位置),如:
@Component
public class Description {
private String name;
private String descripion;
…
在使用時,可以用 @Autowired 或是 @Resource,@Autowired 預設是類型名稱(type),而@Resource 預設是以名稱(Name)來尋找 @Component
@Autowired
@Value("mattrew")
private Description desc;
或是我們用名稱來處理, 其中 @Value 提供一個參數的 Constructor 使用。
@Component(“desc”)
public class Description {
private String name;
private String descripion;
…
使用端編程如下:
@Resource(name=”desc”)
private Description desc;
比較使用端,在@Autowired 時 @Value 是有作用的,但是在@Resouce中就沒有作用。
class Description 範例 (使用 @Component)
@Component("desc")
public class Description {
public Description() {
super();
}
public Description(String name) {
super();
this.setName(name);
}
private void reflashDescription() {
switch (name.toLowerCase()) {
case "mattrew":
this.descripion = "Chapter 1, New Testment.";
break;
case "mark":
this.descripion = "Chapter 2, New Testment.";
break;
case "luke":
this.descripion = "Chapter 3, New Testment";
break;
case "john":
this.descripion = "Chapter 4, New Testment";
break;
default:
this.descripion = "Other than 4 Gospels.";
}
}
private String name;
private String descripion;
public String getDescripion() {
return descripion;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
this.reflashDescription();
}
}