Unsatisfied dependency expressed through field


# 事象 : Invocation of init method failed; nested exception is Can't construct a java object for tag
- 環境
    - Windows10 Pro バージョン1909
    - Eclipse IDE for Enterprise Java Developers Version: 2020-09
    - Apache Tomcat/8.5.61
    - springframework 4.3.24

SpringでYAMLファイルから設定値を読み込もうと思ってYAMLファイルとBeanを準備した。
早速Tomcat起動！したらエラーになった。

<details><summary>EclipseのConsoleに出力されたエラー</summary><div>

```text:コンソールのエラー
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hogeController': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hogeService': Invocation of init method failed; nested exception is Can't construct a java object for tag:yaml.org,2002:com.ponsuke.hogeBean; exception=Class not found: com.ponsuke.hogeBean
 in 'string', line 2, column 3:
      !!com.ponsuke.p ... 
      ^

	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1272)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
```
</div></details>

## 原因 : YAMLの内容をバインドさせるClass名の先頭が小文字だから
思い込みと勢いでやっているとよくある。

```yaml
Hoge :
  !!com.ponsuke.hogeBean
  apiUrl : http://api.e-stat.go.jp/rest/3.0/app/json/getStatsList
```

```java
package com.ponsuke;

public class HogeBean {
    private String ApiUrl;
// ...省略...
```

### 対応 : 先頭を大文字にする

```yaml
Hoge :
  !!com.ponsuke.HogeBean
#...省略...
```
















































# 事象 : expected at least 1 bean which qualifies as autowire candidate.
- 環境
    - Windows10 Pro バージョン1909
    - Eclipse IDE for Enterprise Java Developers Version: 2020-09
    - Apache Tomcat/8.5.61
    - springframework 4.3.24

EclipseでTomcatを起動したらなんか言われてる。

<details><summary>EclipseのConsoleに出力されたエラー</summary><div>

```bash
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hogeService': Unsatisfied dependency expressed through field 'restOperations'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.client.RestOperations' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:364)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1268)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
```
</div></details>

## 原因 : アノテーションがないから
エラーになっているRestOperationsをプロパティに持つhogeServiceは、Mavenでのparent指定先のプロジェクトにあるけれど、起動しているアプリケーションでは使わないもの・・・・以下を読んで気が付いた、新の原因はSpringがよくわかってないから。

> **原因1：アノテーションが付与されていない**
> 初歩的なミスですが、対象クラスをコンテナ管理対象にするためのアノテーションの付け忘れです。
> [Spring BootでNo qualifying bean of typeが出た時の原因と対応 - Qiita](https://qiita.com/NagaokaKenichi/items/058a7243bd2948de7553)

```java
@Service
public class HogeService implements IHogeService {
    @Autowired
    RestOperations restOperations;
//...省略...
```

### 対応 : @Lazyをプロパティにつける
> @Lazyはインスタンスの生成を遅らせることのできるアノテーションで、そのオブジェクトが必要となった時にDIコンテナによって生成されることを意味する。
> @Lazyがない場合は、DIコンテナが起動したときに@Componentが付与されたクラスはいっぺんにインスタンス化される。
> [［改訂新版］Spring入門――Javaフレームワーク・より良い設計とアーキテクチャ](https://gihyo.jp/book/2016/978-4-7741-8217-9)

```java
@Service
public class HogeService implements IHogeService {
    @Autowired @Lazy
    RestOperations restOperations;
//...省略...
```