# Autowired

參考資料:(<https://blog.csdn.net/lipinganq/article/details/79167982>)

在使用 Spring 框架中 使用 `@Autowired` 這個註解 會進行自動注入，這時 在Spring 容器中 必須有可以匹配的 Bean 並且只能有一個。當找不到可以匹配的 Bean 時，會拋出 BeanCreationException，並且指出至少要有一個匹配的。

而當 `@Autowired` 進行注入時，默認按照型態進行注入，當同一個型態存在多個 Bean 的時候，則會按照 Name 去進行注入。

**而且當在Spring中，盡量用 @Autowired 去新增物件，不要直接 new 這樣很容易會因為一些東西沒有注入，而產生 null**

## Error : required a single bean, but 2 were found

參考資料:(<https://stackoverflow.com/questions/46343560/class-required-a-single-bean-but-2-were-found/46344494>)

當 Spring 找到 2個以上的 Bean 時，因為不知道該注入哪一個，所以會丟出這個錯誤。 此時有兩種解法 \~

一種是在你所要使用的 Bean 上方，加上 @Primary 註解，但有人表示不推薦 (我猜測可能是因為， A 和 B 比較時，希望注入B， 但是 B 和 C 比較時，希望注入C，此時可能會造成問題，但我沒有實際嘗試，只是腦補。)

一種是在你要注入的地方，加上 `@Qualifier(想注入的Bean Name)`

```
@Autowired
@Qualifier("magicDao")
private IMagic magicDao;
                  ↑
　　　MagicDao－－－
```

大小寫不能亂打，我原本打成下列的方式，就會出問題

```
@Autowired
@Qualifier("magicDao") //MagicDao //magicDAO 都會出問題
private IMagic magicDAO;
                  ↑
　　　MagicDao－－－
```

參考資料:(<https://zackku.com/spring-scan-problem/>) 也有可能是 Scan 複數個東西，這些東西的內容有交集，可能會導致 Spring 重複掃描，導致有重複的 Bean

解法: 新增一個空的 interface ，讓我們希望被掃描的類別去繼承該interface

```
@MapperScan（basePackages = {“com.zackku.service”}，markerInterface = MapperInterface.class）
```

## expected at least 1 bean which qualifies as autowire candidate.

參考資料:(<https://blog.csdn.net/u014695188/article/details/52263903>)

```
org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'XXXX.XXXX.XXXX.XXXX' available: 
expected at least 1 bean which qualifies as autowire candidate.
```

**解決方法 1** application 那支程式，加入 Scan 看是 MapperScan / ConponentScan 等等，放入對應路徑

或者

```
org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'com.XXX.A.CCCCCCCCIntegrationTests': 
Unsatisfied dependency expressed through field 'httpTools'; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'com.XXX.B.utility.HttpTools' available: 
expected at least 1 bean which qualifies as autowire candidate. 
Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}
```

可以看到 `'com.XXX.A.CCCCCCCCIntegrationTests'` 和 `'com.XXX.B.utility.HttpTools'` 的路徑

因為我直接在 A 裡面 去 `@Autowired` B 的東西，而 B 是某個套件內的 Class。即使我有給 B @Service，他一樣無法去 create bean。

**解決方法 2** 在 A 底下建立一個 Class ，去繼承 B。 這樣就算寫成這樣，也一樣可以成功 `@Autowired`。

```
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Autowired
private HttpTools httpTools;
```
