<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://boniato.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://boniato.github.io/" rel="alternate" type="text/html" /><updated>2021-08-23T16:20:59+00:00</updated><id>https://boniato.github.io/feed.xml</id><title type="html">Boniato Blog</title><subtitle>An website to write what I study.</subtitle><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><entry><title type="html">Chapter4_spring_configuration_in_detail_and_springboot</title><link href="https://boniato.github.io/chapter4_spring_configuration_in_detail_and_springboot/" rel="alternate" type="text/html" title="Chapter4_spring_configuration_in_detail_and_springboot" /><published>2020-07-22T00:00:00+00:00</published><updated>2020-07-22T00:00:00+00:00</updated><id>https://boniato.github.io/chapter4_spring_configuration_in_detail_and_springboot</id><content type="html" xml:base="https://boniato.github.io/chapter4_spring_configuration_in_detail_and_springboot/">&lt;h2 id=&quot;chpater4-스프링-구성-상세와-스프링부트&quot;&gt;chpater4. 스프링 구성 상세와 스프링부트&lt;/h2&gt;

&lt;p&gt;4.1 스프링이 애플리케이션 이식성에 미치는 영향 &lt;br /&gt;
4.2 빈 라이프사이클 관리 &lt;br /&gt;
4.3 빈 생성 시점에 통지 받기 &lt;br /&gt;
4.4 빈 소멸 시점에 통지 받기 &lt;br /&gt;
4.5 빈이 스프링을 알게(Spring Aware)하기 &lt;br /&gt;
4.6 FactoryBean 사용하기 &lt;br /&gt;
4.7 자바빈 PropertyEditor &lt;br /&gt;
4.8 그 외의 스프링 ApplicationContext 구성 살표보기 &lt;br /&gt;
4.9 리소스 접근하기 &lt;br /&gt;
4.10 자바 클래스를 사용한 구성 &lt;br /&gt;
4.11 프로파일 &lt;br /&gt;
4.12 Environment와 PropertySource 추상화 &lt;br /&gt;
4.13 JSR-330 애너테이션을 사용한 구성 &lt;br /&gt;
4.14 그루비를 사용한 구성 &lt;br /&gt;
4.15 스프링 부트 &lt;br /&gt;
4.16 정리 &lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;4.3.1 빈 생성시 메서드 실행하기&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;초기화 콜백을 받는 방법 중 하나는 빈의 메서드 하나를 지정해 초기화 콜백으로 사용하겠다고 스프링에 설정하는 것&lt;/li&gt;
  &lt;li&gt;이런 콜백 메커니즘은 같은 타입의 빈이 몇 개 안 되거나 애플리케이션이 스프링과 결합되지 않게 할 때 유용&lt;/li&gt;
  &lt;li&gt;이 메커니즘을 사용하는 또 다른 이유로 스프링 기반 애플리케이션이 이전에 만들어진 빈이나 서드파티 벤더가 제공하는 빈을 사용해야 할 때를 들 수 있음&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;콜백 메서드를 지정하려면 빈을 정의하는 &lt;bean&gt; 태그에 init-method 애트리뷰트로 메서드 이름을 설정함.&lt;/bean&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;다음은 의존성 두 개가 필요한 간단한 빈의 코드&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;예제 4-1 초기화 콜백 메서드가 정의된 Singer 클래스([[bean-init-method]] Singer.java)
```java
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;public class Singer {
    private static final String DEFAULT_NAME = “Eric Clapton”;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;private String name;
private int age = Integer.MIN_VALUE;

public void setName(String name) {
    this.name = name;
}

public void setAge(int age) {
    this.age = age;
}

private void init() {
    System.out.println(&quot;빈 초기화&quot;);

    if (name == null) {
        System.out.println(&quot;기본 이름 사용&quot;);
        name = DEFAULT_NAME;
    }

    if (age == Integer.MIN_VALUE) {
        throw new IllegalArgumentException(
                Singer.class +&quot; 빈 타입에는 반드시 age 프로퍼티를 설정해야 합니다.&quot;);
    }
}

public String toString() {
    return &quot;\t이름: &quot; + name + &quot;\n\t나이: &quot; + age;
}

public static void main(String... args) {
    GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
    ctx.load(&quot;classpath:spring/app-context-xml.xml&quot;);
    ctx.refresh();

    getBean(&quot;singerOne&quot;, ctx);
    getBean(&quot;singerTwo&quot;, ctx);
    getBean(&quot;singerThree&quot;, ctx);

    ctx.close();
}

public static Singer getBean(String beanName, ApplicationContext ctx) {
    try {
        Singer bean = (Singer) ctx.getBean(beanName);
        System.out.println(bean);
        return bean;
    } catch (BeanCreationException ex) {
        System.out.println(&quot;빈 구성 도중 에러 발생: &quot;
                + ex.getMessage());
        return null;
    }
} } ```
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;이 예제에서 콜백 메서드로 작동할 init() 메서드를 정의한 점에 주목&lt;/li&gt;
  &lt;li&gt;init() 메서드는 name 프로퍼티가 설정됐는지 확인하고 프로퍼티가 설정되지 않았으면 DEFAULT_NAME 상수에 선언된 값을 기본값으로 설정&lt;/li&gt;
  &lt;li&gt;또한, init() 메서드는 age 프로퍼티가 설정됐는지 점검해 설정되지 않았으면 IllegalArgumentException 예외를 던짐&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;예제 4-2 Singer 빈 및 초기화 콜백 메서드 구성([[bean-init-method]] app-context-xml.xml)
```xml
&amp;lt;?xml version=”1.0” encoding=”UTF-8”?&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:p=&quot;http://www.springframework.org/schema/p&quot; xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd&quot; default-lazy-init=&quot;true&quot;&gt;

    &lt;bean id=&quot;singerOne&quot; class=&quot;com.apress.prospring5.ch4.Singer&quot; init-method=&quot;init&quot; p:name=&quot;John Mayer&quot; p:age=&quot;39&quot; /&gt;

    &lt;bean id=&quot;singerTwo&quot; class=&quot;com.apress.prospring5.ch4.Singer&quot; init-method=&quot;init&quot; p:age=&quot;72&quot; /&gt;

    &lt;bean id=&quot;singerThree&quot; class=&quot;com.apress.prospring5.ch4.Singer&quot; init-method=&quot;init&quot; p:name=&quot;John Butler&quot; /&gt;
&lt;/beans&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&amp;lt;br&amp;gt;
&amp;lt;br&amp;gt;

## 4.15 스프링 부트

지금까지 스프링 애플리케이션을 구성하는 여러 가지 방법을 살펴봤습니다. 이제 스프링을 구성할 때 XML, 애너테이션, 자바 구성 클래스, 그루비 스크립트 또는 이 모든 것을 함께 사용하는 방법에 대한 기초 지식을 이해하고 있어야 합니다. 그런데 이들보다 훨씬 근사한 방법이 있다면 어떨까요?

스프링 부트(Spring Boot) 프로젝트는 처음 스프링을 사용해 애플리케이션을 만드는 작업을 간단하게 하려는 데 목적이 있습니다. 스프링 부트는 사용자가 필요한 의존성을 직접 추측해서 모으는 작업을 없애고 측정(metrics)5이나 상태 점검(health check)처럼 대부분 애플리케이션이 필요로 하는 몇 가지 공통 기능을 제공합니다.

스프링 부트는 다양한 유형의 애플리케이션에 맞는 시작 프로젝트를 제공하는데 이들 프로젝트에는 이미 적절한 의존성 및 버전이 포함돼 있습니다. 스프링 부트는 이와 같은 “완고한(opinionated)” 접근법으로 개발자의 노력을 단순화하며 개발 시작에 들어가는 시간을 줄여줍니다. 또한, 스프링 부트는 구성 XML을 완전히 없애려는 개발자를 타겟으로 해, XML 기반 구성이 전혀 필요하지 않습니다.

이번 예제에서는 고전적인 Hello World 웹 애플리케이션을 조금 다르게 만들어보겠습니다. 아마도 일반적인 웹 애플리케이션 초기 설정과 비교해 볼 때 정말 적은 양의 코드만 작성하면 되는 것에 놀라게 될 것입니다. 일반적인 스프링 예제는 먼저 프로젝트에 추가해야 하는 의존성을 정의하는 작업부터 시작했습니다. 스프링 부트가 제공하는 단순화 모델의 한 부분은 개발에 필요한 의존성을 사전에 준비하는 것입니다. 예를 들어 메이븐을 사용하면 개발자는 부모 POM을 사용해 필요한 의존성을 얻을 수 있습니다. 그레이들을 사용하면 이 작업이 더 간단해집니다. 그레이들 플러그인과 starter 의존성을 제외하면 부모 프로젝트도 필요하지 않습니다. 다음 예제에서는 컨텍스트에 있는 모든 빈 목록을 가져온 뒤 helloWorld 빈에 접근합니다. boot-simple 프로젝트의 그레이들 구성은 다음과 같습니다.

* 예제 4-100 스프링 부트 프로젝트 그레이들 빌드 파일([[boot-simple]] build.gradle)

```java
buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
        maven { url &quot;http://repo.spring.io/release&quot; }
        maven { url &quot;http://repo.spring.io/snapshot&quot; }
        maven { url &quot;https://repo.spring.io/libs-snapshot&quot; }
        maven { url &quot;http://repo.spring.io/milestone&quot; }
        maven { url &quot;https://repo.spring.io/libs-milestone&quot; }
    }

    dependencies {
        classpath boot.springBootPlugin
    }
}

apply plugin: 'org.springframework.boot'

dependencies {
    compile boot.starter
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;boot.springBootPlugin 줄은 부모 프로젝트의 build.gradle 파일에 정의된 boot 배열의 springBootPlugin 프로퍼티를 참조합니다. 부모 프로젝트의 build.gradle 파일 내용(스프링 부트에만 관련 있는 구성)은 다음과 같습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;예제 4-101 부모 프로젝트의 build.gradle&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bootVersion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;RELEASE&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;boot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;springBootPlugin:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;org.springframework.boot:spring-boot-gradle-plugin:$bootVersion&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;starter:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;org.springframework.boot:spring-boot-starter:$bootVersion&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nl&quot;&gt;starterWeb:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;springframework&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;starter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;web:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;$bootVersion&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;스프링 부트는 버전별로 지원하는 의존성 관리 목록을 갖고 있습니다. 필요한 라이브러리의 버전이 사전에 선택돼 있어 API가 완벽히 일치하게 되며, 이런 라이브러리와 버전은 스프링 부트가 관리합니다. 그러므로 수작업으로 의존성을 관리할 필요가 없습니다. 스프링 부트를 업그레이드하면 이런 의존성도 같이 업그레이드됩니다. 앞서 살펴본 구성을 사용하면 API 호환이 보장되는 적절한 버전의 의존성이 프로젝트에 추가될 것입니다. IntelliJ IDEA나 이클립스 같은 스마트 편집기에서는 프로젝트에 추가된 의존성 목록을 확인할 수 있습니다. IntelliJ를 사용할 때는 Gradle Projects 뷰에서 각 모듈을 펼쳐 사용 가능한 작업과 의존성 목록을 확인할 수 있습니다.&lt;/p&gt;

&lt;p&gt;설정을 마쳤으니 클래스를 생성해 보겠습니다. HelloWorld 클래스는 다음과 같습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;예제 4-102 HelloWorld 클래스([[boot-simple]] HelloWorld.java)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.apress.prospring5.ch4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.slf4j.Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelloWorld&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Logger&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
        &lt;span class=&quot;nc&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HelloWorld&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sayHi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello World!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이 클래스는 특별하지도 복잡하지도 않으며, 메서드 하나가 정의돼 있고 빈 선언용 애너테이션이 적용돼 있을 뿐입니다. 스프링 부트를 사용해 어떻게 애플리케이션을 만들고 이 빈을 담는 ApplicationContext를 생성하는지 알아보겠습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;예제 4-103 빈을 사용하는 스프링 부트 테스트 코드([[boot-simple]] Application.java)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.slf4j.Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.boot.SpringApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.boot.autoconfigure.SpringBootApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.context.ConfigurableApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.util.Arrays&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Application&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Logger&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoggerFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;ConfigurableApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; 
          &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SpringApplication&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;빈을 검색하는 중:&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// listing all bean definition names&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Arrays&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBeanDefinitionNames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;logger:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;HelloWorld&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HelloWorld&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sayHi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이게 코드의 전부입니다. 물론 이 클래스를 더 작게 만들 수 있었지만 추가로 몇 가지 기능을 더 보여주고 싶었습니다. 추가 기능에 어떤 것이 있는지 확인해 보겠습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;컨텍스트를 가져왔는지 확인하기&lt;/strong&gt;: ctx가 null이 아니라는 가정을 테스트하려고 assert 문을 사용했습니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;로그 설정&lt;/strong&gt;: 스프링 부트는 몇 가지 로깅 라이브러리를 제공하므로 사용하고자 하는 라이브러리의 설정을 resources 디렉터리에 넣어 주기만 하면 됩니다. 앞 예제에서는 logback 로깅 라이브러리를 선택했습니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;컨텍스트에 정의된 모든 빈 목록 가져오기&lt;/strong&gt;: 자바 8 람다식을 사용하면 코드 한 줄로 컨텍스트 내에 정의된 모든 빈 목록을 가져올 수 있습니다. 해당 코드를 추가해 어떤 빈이 스트링 부트에 의해 자동으로 구성되는지 확인할 수 있습니다. 물론 목록에서 helloWorld 빈도 확인할 수 있을 것입니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;애플리케이션 종료 확인&lt;/strong&gt;: System.in.read() 메서드가 없으면 애플리케이션은 빈 이름을 출력하고 HelloWorld 출력 후 바로 종료됩니다. 코드에 System.in.read() 메서드 호출을 추가해 애플리케이션이 개발자가 키를 누를 때까지 대기하도록 하며, 키를 누른 후에는 애플리케이션이 종료되도록 합니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;@SpringBootApplication은 처음 보는 애너테이션으로 클래스 레벨에서만 사용하도록 설계된 최상위 애너테이션입니다. @SpringBootApplication 애너테이션은 다음 세 애너테이션을 모두 정의한 것과 같은 편리한 애너테이션입니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;@Configuration&lt;/strong&gt;: 이 애너테이션은 해당 클래스가 @Bean으로 빈을 정의하는 구성 클래스임을 나타냅니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;@EnableAutoConfiguration&lt;/strong&gt;: 이 애너테이션은 org.springframework.boot.autoconfigure에 들어있는 특수한 스프링 부트 애너테이션으로 제공된 의존성을 기반으로 사용자가 필요로 할 빈을 추측해 구성한 뒤 스프링 ApplicationContext를 활성화합니다. @EnableAutoConfiguration은 스프링 부트가 제공하는 스타터 의존성과 잘 작동하지만 여기에 결합된 것은 아니므로 스타터 외의 의존성도 사용할 수 있습니다. 예를 들어 클래스패스에 특정 임베디드 서버가 있다면 또 다른 EmbeddedServletContainerFactory 구성이 프로젝트 내에 존재하지 않는 이상 이 임베디드 서버를 사용합니다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;@ComponentScan&lt;/strong&gt;: 사용할 클래스에 스테레오타입 애너테이션을 지정해 몇 가지 유형의 빈으로 선언할 수 있습니다. @SpringBootApplication에 스캔 대상 패키지 목록을 나타낼 때 사용하는 애트리뷰트는 basePackages입니다. 버전 1.3.0부터 컴포넌트 스캔 대상을 나타낼 때 사용 가능한 애트리뷰트로 basePackageClasses가 추가됐습니다. 이 애트리뷰트는 basePackages의 대안으로 사용되는데, 애너테이션이 적용된 컴포넌트 스캔 대상 패키지를 지정할 때 기존처럼 패키지 문자열을 지정하지 않고 패키지 내 클래스를 명시적으로 지정할 수 있어 basePackages보다 안전합니다. 또한, 스캔 대상 클래스를 여러 개 지정해 여러 패키지에서 컴포넌트를 스캔할 수 있습니다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;@SpringBootApplication 애너테이션에 컴포넌트 스캔 관련 애트리뷰트를 정의하지 않으면 @ SpringBootApplication을 붙인 클래스가 위치한 패키지만을 검색합니다. 이것이 이전 예제에서 helloWorld 빈 정의를 찾아 빈을 생성할 수 있던 이유입니다.&lt;/p&gt;

&lt;p&gt;이전 예제의 스프링 부트 애플리케이션은 즉시 사용 가능한 환경에서 개발자가 정의한 빈 하나만을 가진 단순한 콘솔 애플리케이션이었습니다. 하지만 스프링 부트는 웹 애플리케이션을 위한 스타터 의존성도 제공합니다. 이때 사용하는 의존성은 spring-boot-starter-web으로 그림 4-4에서 이 스프링 부트 스타터 라이브러리의 전이 의존성(transitive dependencies)를 확인할 수 있습니다. boot-web 프로젝트에서 HelloWorld 클래스는 스프링 컨트롤러(스프링 웹에서 빈 생성에 사용되는 특수한 타입의 클래스)입니다. 이 HelloWorld 클래스는 전형적인 스프링 MVC 컨트롤러 클래스로 16장에서 관련 내용을 알아보겠습니다.&lt;/p&gt;</content><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><summary type="html">chpater4. 스프링 구성 상세와 스프링부트</summary></entry><entry><title type="html">Chapter3_spring_ioc_and_di</title><link href="https://boniato.github.io/chapter3_spring_IoC_and_DI/" rel="alternate" type="text/html" title="Chapter3_spring_ioc_and_di" /><published>2020-07-07T00:00:00+00:00</published><updated>2020-07-07T00:00:00+00:00</updated><id>https://boniato.github.io/chapter3_spring_IoC_and_DI</id><content type="html" xml:base="https://boniato.github.io/chapter3_spring_IoC_and_DI/">&lt;h2 id=&quot;chpater3-스프링-ioc와-di&quot;&gt;chpater3. 스프링 IoC와 DI&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;3.1 IoC와 DI &lt;br /&gt;
3.2 IoC의 종류 &lt;br /&gt;
3.3 스프링의 제어 역전 &lt;br /&gt;
3.4 스프링의 의존성 주입 &lt;br /&gt;
3.5 애플리케이션 컨텍스트 구성하기 &lt;br /&gt;
3.6 빈에 자동와이어링하기 &lt;br /&gt;
3.7 빈 상속 설정하기&lt;/strong&gt; &lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;살펴보기
    &lt;ul&gt;
      &lt;li&gt;스프링 깃허브 저장소 주소 : https://github.com/spring-projects/spring-framework&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;스냅샷(snapshot) 빌드&lt;/strong&gt;란 아직 정식 버전이 공개되지 않은 개발 버전의 마지막 버전을 나타냄.&lt;br /&gt;
만약 1.0-SNAPSHOT과 같이 버전이 붙은 파일이 있다면 이는 1.0 정식 배포 전 해당 라이브러리를 개발 중임을 나타냅니다. 또한, 스냅샷은 받는 시점에 따라 파일에 담긴 내용이 바뀔 수 있음.&lt;/li&gt;
      &lt;li&gt;스프링 5.1이 공식 지원하는 자바 버전은 자바 11이며, 최소 자바 8이 필요합니다.&lt;/li&gt;
      &lt;li&gt;후보 컴포넌트 인덱스 기능은 스프링 5.0에 처음 도입된 기능으로, 이를 통해 클래스패스 기반 컴포넌ㄴ트 스캔을 대체할 수 있음. 이를 사용하면 무거운 애플리케이션의 기동 시간 개선에 큰 효과가 있음.&lt;/li&gt;
      &lt;li&gt;전이 의존성(transitive dependency)이란 개발 중인 애플리케이션이 A 라이브버리를 필요로 하고 A 라이브러리가 내부적으로 B 라이브러리를 필요로 하는 경우, 애플리케이션이 B 라이브러로도 필요로 한다고 간주하는 것.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;빈(bean)은 스프링에서 클래스의 인스턴스를 의미&lt;/strong&gt;함.&lt;/li&gt;
      &lt;li&gt;이클립스는 인텔리제이 IDEA와 다르게 의존성을 트리 형태로 보여주지 않음. 그러나 빌드 구성 파일에 지정하지 않은 aop, beans 등의 모듈이 있는 것을 보면 그레이들이 전이 의존성을 통해 필요한 모든 라이브러리를 받았음을 알 수 있음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;IoC와 DI의 주 목적 : &lt;strong&gt;컴포넌트의 의존성을 제공&lt;/strong&gt;하고 &lt;strong&gt;이러한 의존성을 라이프사이클 전반에 걸쳐 관리&lt;/strong&gt;하는 보다 간편한 메커니즘을 제공하는 것.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;IoC(Inversion of Control, 제어의 역행) 두 가지 하위분류로 나눌 수 있음
    &lt;ul&gt;
      &lt;li&gt;의존성 주입(Dependency Injection, DI)&lt;/li&gt;
      &lt;li&gt;의존성 룩업(Dependency Lookup, DL)
        &lt;ul&gt;
          &lt;li&gt;이들은 다시 구체적인 IoC 구현체로 나늼.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;IoC 종류
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;의존성 주입(DI)&lt;/strong&gt; : 이 방식의 IoC에서는 IoC &lt;strong&gt;컨테이너가 컴포넌트에 의존성을 주입&lt;/strong&gt;합니다.&lt;br /&gt;
        &lt;ul&gt;
          &lt;li&gt;덧붙여 설명하자면..&lt;/li&gt;
          &lt;li&gt;Martin Fowler가 제어의 어떠한 부분이 반전되는가라는 질문에 ‘의존 관계 주입’이라는 용어를 사용하였다고 함.&lt;/li&gt;
          &lt;li&gt;의존성 주입(DI)은 프로그래밍에서 구성요소간의 의존 관계가 소스코드 내부가 아닌 &lt;strong&gt;외부의 설정파일 등을 통해 정의&lt;/strong&gt;되게 하는 디자인 패턴 중 하나.
            &lt;ul&gt;
              &lt;li&gt;여기서 외부 설정파일은 스프링 설정파일을 의미하며, &lt;strong&gt;스프링 설정파일을 통하여 객체간의 의존관계를 설정&lt;/strong&gt;&lt;/li&gt;
              &lt;li&gt;스프링 컨테이너(Spring Container)가 제공하는 API를 이용해 객체를 사용.&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;각 클래스간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것.
            &lt;ul&gt;
              &lt;li&gt;생성자(constructor) 의존성 주입&lt;/li&gt;
              &lt;li&gt;수정자(setter) 의존성 주입&lt;/li&gt;
              &lt;li&gt;메소드(Method Injection) 의존성 주입(책에서는 없는 내용이지만 추가함.)&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;의존성 룩업(DL)&lt;/strong&gt; : 이 방식의 IoC에서는 &lt;strong&gt;컴포넌트 스스로 의존성의 참조를 가져와야&lt;/strong&gt; 합니다.
        &lt;ul&gt;
          &lt;li&gt;저장소에 저장되어 있는 Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 Lookup하는 것.
            &lt;ul&gt;
              &lt;li&gt;의존성 풀(Dependency Pull)&lt;/li&gt;
              &lt;li&gt;의존성 룩업(CDL)&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Spring DI 컨테이너&lt;/strong&gt; (책에 없는 내용)
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;빈(Bean)&lt;/strong&gt; : Spring DI 컨테이너가 관리하는 객체&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;빈 팩토리(Bean Factory)&lt;/strong&gt; : 빈(Bean)들을 관리하는 컨테이너. Bean(객체) 등록, 생성, 조회, 반환 관리. 빈 객체간의 의존관계 설정해주는 기능 제공.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;어플리케이션 컨텍스트(Application Context)&lt;/strong&gt; : 빈 팩토리(Bean Factory)에 여러가지 컨테이너 기능을 추가한 것(추가 기능: AOP, 메시지 지원, 국제화 지원 등). 보통은 BeanFactory를 바로 사용하지 않고, 이를 확장한 Application Context를 사용.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;스프링 컨테이너(Spring Container)&lt;/strong&gt; : 설정파일에 설정된 내용을 읽어 Application에서 필요한 기능들을 제공. 객체를 관리.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;스프링 설정파일&lt;/strong&gt; : Spring Container가 어떻게 일할지를 설정하는 파일. XML 기반으로 작성. RootTag는 &lt;beans&gt;임.
&lt;/beans&gt;        &lt;ul&gt;
          &lt;li&gt;ex.) applicationContext.xml
            &lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

      &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;oracle&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;wiseworm&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.BookwormOracle&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;            &lt;/div&gt;
          &lt;/li&gt;
          &lt;li&gt;여기서 &lt;bean&gt; 태그는 스프링 컨테이너가 관리할 Bean객체를 설정하는 것임.&lt;/bean&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;3.2.1 &lt;strong&gt;의존성 풀(Dependency Pull)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;의존성 풀에서는 필요에 따라 레지스트리에서 의존성을 가져오게 됩니다.&lt;br /&gt;
ex) JNDI API를 사용한 EJB 컴포넌트 룩업&lt;br /&gt;&lt;/li&gt;
      &lt;li&gt;JNDI(Java Naming and Directory Interface)는
        &lt;ul&gt;
          &lt;li&gt;디렉터리 서비스에서 제공하는 데이터 및 객체를 발견(discover)하고 참고(lookup)하기 위한 자바 API&lt;/li&gt;
          &lt;li&gt;서버에서 관리하고 있는 리소스에 대한 정보를 알고 있고 특정 리소스를 찾아서 사용할 수있도록 객체를 반환&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;         &lt;span class=&quot;c1&quot;&gt;// lookup 소스..&lt;/span&gt;

         &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DatabaseManager&lt;/span&gt;
         &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getConnection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
               &lt;span class=&quot;nc&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;InitialContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
               &lt;span class=&quot;nc&quot;&gt;DataSource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;DataSource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;java:comp/env/jdbc/myoracle&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
               &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getConnection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
         &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;스프링 프레임워크도 자신이 관리하는 컴포넌트를 가져오는 메커니증 중 하나로서 의존성 풀을 제공&lt;/li&gt;
  &lt;li&gt;의존성 풀 사용 예&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.apress.prospring5.ch3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.apress.prospring5.ch2.decoupled.MessageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.context.ApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.context.support.ClassPathXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DependencyPull&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;ApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClassPathXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;spring/app-context.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;renderer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;3.2.2 문맥에 따른 &lt;strong&gt;의존성 룩업(CDL)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;의존성 풀처럼 특정 중앙 레지스트리에서 의존성을 가져오는 것이 아니라 &lt;strong&gt;자원을 관리하는 컨테이너&lt;/strong&gt;에서 의존성을 가져옴. &amp;lt;- 풀, 룩업 차이점!&lt;/li&gt;
      &lt;li&gt;늘 수행되는 것이 아니라 몇 사기 정해진 시점에 수행&lt;/li&gt;
      &lt;li&gt;다음은 문맥에 따른 의존성 룩업 메커니즘
        &lt;ul&gt;
          &lt;li&gt;의존 객체 -&amp;gt; 룩업 -&amp;gt; 컨테이너&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;컨테이너에서 의존성을 가져오는 컴포넌트&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContextualizedDependencyLookup&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ManagedComponent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dependency&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 1)의존성 룩업을 수행하는 메소드&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;performLookup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Container&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dependency&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;myDependency&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3.2.3 생성자 의존성 주입&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;컴포넌트의 생성자(또는 여러 생성자)를 이용해서 해당 컴포넌트가 필요로하는 의존성을 제공하는 방식.&lt;/li&gt;
  &lt;li&gt;어떤 컴포넌트가 의존성을 인수로 가져오도록 생성자 또는 여러 생성자를 선언한다면 IoC 컨테이너는 해당 컴포넌트를 초기화할 때 컴포넌트에 필요한 의존성을 전달함.&lt;/li&gt;
  &lt;li&gt;주의점 : 생성자 주입을 사용할 때 의존성 주입 없이는 빈을 생성할 수 없으므로 &lt;strong&gt;반드시 의존성을 주입&lt;/strong&gt;해야함!&lt;/li&gt;
  &lt;li&gt;생성자 의존성 주입 예제 코드&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConstructorInjection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dependency&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConstructorInjection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Dependency&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dependency&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3.2.4 수정자 의존성 주입&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;수정자(setter) 의존성 주입 방식에서 IoC 컨테이너는 자바빈 방식의 &lt;strong&gt;수정자 메서드&lt;/strong&gt;를 이용해 컴포넌트의 의존성을 주입.&lt;/li&gt;
  &lt;li&gt;컴포넌트의 수정자는 &lt;strong&gt;IoC 컨테이너가 관리할 수 있도록 의존성을 노출&lt;/strong&gt;함.&lt;/li&gt;
  &lt;li&gt;수정자 주입을 사용할 때 명확한 것은 의존성 없이도 객체를 생성할 수 있으며 해당 수정자를 호출해 의존성을 나중에 제공할 수 있음.&lt;/li&gt;
  &lt;li&gt;의존성 주입이 필요한 일반적인 컴포넌트 예제&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SetterInjection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dependency&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setDependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Dependency&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dependency&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependency&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3.2.5 &lt;strong&gt;의존성 주입&lt;/strong&gt; vs. 의존성 룩업&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;현재 사용하는 컨테이너에 따라 IoC의 방식이 정해짐&lt;/li&gt;
  &lt;li&gt;ex) EJB 2.1 이하 버전을 사용할 때 EJB를 JEE 컨테이너에서 가져오려면 의존성 룩업(JNDI를 통한) 방식의 IoC를 사용해야 함.
    스프링에서는 초기 빈 룩업을 제외하면 컴포넌트와 의존성은 항상 의존성 주입 방식의 IoC를 이용해 연결됨.&lt;/li&gt;
  &lt;li&gt;주입 방식을 선택하는 가장 큰 이유는 의존성 주입을 사용하면 그만큼 개발이 쉬워지기 때문. 작성해야 하는 코드량 줄이고 코드도 간결. IDE를 이용해 자동화도 가능.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;주입 코드&lt;/strong&gt;는 &lt;strong&gt;객체가 필드에만 저장&lt;/strong&gt;됨. 저장소나 컨테이너에서 의존성을 가져오는 코드가 전혀 필요하지 않음. 따라서 코드는 훨씬 단순해지고 에러도 줄어듬.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.2.6 &lt;strong&gt;수정자 주입&lt;/strong&gt; vs. &lt;strong&gt;생성자 주입&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;생성자 주입(constructor injection)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;컴포넌트 사용 전에 해당 컴포넌트의 의존성을 반드시 갖고 있어야 할 때 매우 유용&lt;/strong&gt;. 의존성 점검 메커니즘을 제공하는지와 상관없이 의존성에 대한 요구사항 지정 가능.&lt;/li&gt;
      &lt;li&gt;빈 객체를 불변 객체로 사용 가능.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;수정자 주입(setter injection)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;기존 의존성을 제공할 때 일반적으로 &lt;strong&gt;수정자 주입이 의존성 주입에 가장 좋은 방법&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;인터페이스에서 모든 의존성을 선언할 수 있음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;의존성 주입 메소드를 비즈니스 인터페이스에서 정의하지 않고, 비즈니스 인터페이스를 구현하는 클래스에서 이 메소드를 정의!&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Oracle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;defineMeaningOfLife&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BookwormOracle&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Oracle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Encyclopedia&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encyclopedia&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setEncyclopedia&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Encyclopedia&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encyclopedia&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;encyclopedia&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encyclopedia&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;defineMeaningOfLife&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Encyclopedias are a waste of money -  go see the world instead&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;BookwormOracle 클래스는 Oracle 인터페이스를 구현했을 뿐만 아니라 의존성 주입을 위한 수정자도 정의&lt;/li&gt;
  &lt;li&gt;스프링은 이와 같은 구조를 다루는데 훨씬 더 편리&lt;/li&gt;
  &lt;li&gt;여기서 비즈니스 인터페이스에서 의존성을 정의할 필요없음&lt;/li&gt;
  &lt;li&gt;의존성을 정의하는 인터페이스를 사용할 수 있다는 것이 수정자 주입의 잘 알려진 장점!
    &lt;ul&gt;
      &lt;li&gt;하지만 실제로는 주입을 위한 수정자가 사용자 인터페이스의 외부에 존재하도록 노력해야함&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3.3 스프링 제어 역전&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;제어 역전(Inversion of Control, IoC)은 스프링이 하는 일 중에 가장 큰 부분을 차지!&lt;/li&gt;
  &lt;li&gt;의존성 룩업 기능이 제공되지만, &lt;strong&gt;스프링 구현의 핵심은 의존성 주입&lt;/strong&gt;임!
    &lt;ul&gt;
      &lt;li&gt;스프링의 의존성 주입 메커니증
[의존 객체] &amp;lt;——의존성 주입——- [스프링 BeanFactory 컨테이너]&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.4 &lt;strong&gt;빈(Bean)과 빈 팩터리(Bean Factory)&lt;/strong&gt;
&lt;strong&gt;스프링의 의존성 주입 컨테이너의 핵심&lt;/strong&gt;은 &lt;strong&gt;빈 백터리 인터페이스&lt;/strong&gt; 입니다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;빈 팩터리(Bean Factory)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;컴포넌트 관리&lt;/li&gt;
      &lt;li&gt;컴포넌트의 라이프사이클뿐만 아니라 의존성까지 관리&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.4.2 &lt;strong&gt;BeanFactory 구현체&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;독립 실행형 자바 어플리케이션에서 원하는 처리를 하기 위해 스프링의 BeanFactory를 초기화하고 oracle 빈을 가져오는 방법 코드&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;XmlConfigWithBeanFactory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	        &lt;span class=&quot;c1&quot;&gt;// BeanFactory 구현체 중 하나인 DefaultListableBeanFactory 사용&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;DefaultListableBeanFactory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DefaultListableBeanFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		
		&lt;span class=&quot;c1&quot;&gt;// XmlBeanDefinitionReader를 사용해 XML 파일의 BeanDefinition 정보 읽음&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;XmlBeanDefinitionReader&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rdr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;XmlBeanDefinitionReader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		
		&lt;span class=&quot;n&quot;&gt;rdr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;loadBeanDefinitions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClassPathResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;spring/xml-bean-factory-config.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
		
		&lt;span class=&quot;c1&quot;&gt;// oracle 빈을 가져오기&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Oracle&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oracle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Oracle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;oracle&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		
		&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;oracle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;defineMeaningOfLife&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;xml-bean-factory-config.xml&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
    
&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;oracle&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;wiseworm&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.BookwormOracle&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3.4.3 &lt;strong&gt;애플리케이션 컨텍스트(ApplicationContext)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;스프링의 애플리케이션 컨텍스트 인터페이스는 &lt;strong&gt;BeanFactory를 상속한 인터페이스&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;DI 서비스 외에도 트랜잭션 서비스, AOP 서비스, 국제화(il8n)를 위한 메시지 소스, 애플리케이션 이벤트 처리와 같은 여러 서비스 제공&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;스프링 기반 애플리케이션 개발 할 때 &lt;strong&gt;ApplicationContext 인터페이스&lt;/strong&gt;를 이용해 스프링을 사용하는 것을 권장!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;스프링은 ApplicationContext를
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;직접 코드&lt;/strong&gt;로 &lt;strong&gt;부트스트랩&lt;/strong&gt;(직접 인스턴스를 생성하고 적절한 애플리케이션 구성을 불러오는 방식)하거나&lt;/li&gt;
      &lt;li&gt;웹 컨테이너 환경에서 &lt;strong&gt;ContextLoaderListener를 이용&lt;/strong&gt;해 부트스트랩 합니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;BeanFactory «‘interface» &lt;br /&gt;
              ↑&lt;/li&gt;
  &lt;li&gt;ApplicationContext «‘interface» &lt;br /&gt;
              ↑&lt;/li&gt;
  &lt;li&gt;WebApplicationContext «‘interface»&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;빈(bean) 객체 주입 받기&lt;/strong&gt; (책에 없는 내용)
    &lt;ul&gt;
      &lt;li&gt;설정파일 설정
        &lt;ul&gt;
          &lt;li&gt;
            &lt;bean&gt; : 스프링 컨테이너가 관리할 bean 객체를 설정
  
&lt;/bean&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

            &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dao&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.spring5.ch3.model.MemberDAO&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;설정 파일에 설정한 내용을 바탕으로 Spring API를 통해 객체를 주입 받는다.
    &lt;ul&gt;
      &lt;li&gt;설정파일이 어디 있는지 설정&lt;/li&gt;
      &lt;li&gt;객체를 만들어 주는 (Assembler) 객체 생성&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;  &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;//설정파일이 어디 있는지를 저장하는 객체&lt;/span&gt;
      &lt;span class=&quot;nc&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClassPathResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;applicationContext.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;//객체를 생성해주는 factory 객체&lt;/span&gt;
      &lt;span class=&quot;nc&quot;&gt;BeanFactory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;XmlBeanFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;//설정파일에 설정한 &amp;lt;bean&amp;gt; 태그의 id/name을 통해 객체를 받아온다.&lt;/span&gt;
      &lt;span class=&quot;nc&quot;&gt;MemberDAO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dao&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MemberDAO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dao&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3.5.1 스프링 구성 옵션 설정하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;스프링에서 애플리케이션 구성을 정의할 수 있는 옵션
    &lt;ul&gt;
      &lt;li&gt;빈(bean) 정의 : 프로퍼티 or XML 파일을 사용해 빈 정의할 수 있도록 지원&lt;/li&gt;
      &lt;li&gt;JDK 5가 출시되고, 스프링이 자바 애너테이션 지원하면서 스프링 2.5부터는 ApplicationContext를 구성하는데 자바 애너테이션을 지원하기 시작!&lt;/li&gt;
      &lt;li&gt;XML과 애너테이션 방식 중 어느것이 더 나을까? -&amp;gt; 각 장단점이 있기에 정답 없음.
        &lt;ul&gt;
          &lt;li&gt;XML 파일을 사용하면 모든 구성을 자바에서 분리해 외부에서 관리&lt;/li&gt;
          &lt;li&gt;애너테이션을 사용하면 개발자가 코드 내에서 DI 구성을 정의하고 확인 가능&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;일반적인 접근 중 하나는
        &lt;ul&gt;
          &lt;li&gt;XML 파일에 애플리케이션의 인프라(예를 들어 데이터 소스, 트랜잭션 관리자, JMS 연결 팩터리(Connection Factory), JMX 등) 정의하고&lt;/li&gt;
          &lt;li&gt;애너테이션으로 DI 구성(주입 가능 빈과 빈의 의존성)을 정의하는 방식
=&amp;gt; 어떤 옵션을 선택하는지, 선택한 방법을 일관성 있게 준수하고 전체 개발팀이 분명히 이해할 수 있게 메시지를 명확히 전달&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.5.2 기본 구성의 개요&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;XML 구성을 사용&lt;/strong&gt;하려면 애플리케이션에서 필요한 &lt;strong&gt;스프링 네임스페이스 베이스&lt;/strong&gt;를 선언해야함&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;스프링 빈 정의에 사용하는 네임스페이스 선언의 예 (app-context-xml.xml)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xmlns:p=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/p&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;renderer&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.annotated.StandardOutMessageRenderer&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;p:messageProvider-ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;provider&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;provider&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.annotated.HelloWorldMessageProvider&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;컴포넌트 스캔(component-scan)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;지정한 패키지의 모든 하위 패키지에 있는 클래스에 애너테이션이 선언된 클래스를 찾아(스캔) 자동으로 bean을 생성&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;컴포넌트 스캐닝 설정&lt;/strong&gt;을 한 XML 구성 파일 (app-context-annotation.xml)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xmlns:context=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/context&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;context:component-scan&lt;/span&gt; 
          &lt;span class=&quot;na&quot;&gt;base-package=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.annotated&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;**&lt;context:component-scan&gt; 태그**는
&lt;/context:component-scan&gt;    &lt;ul&gt;
      &lt;li&gt;**지정한 패키지의 모든 하위 패키지에 있는 클래스에 선언된 @Autowired, @Inject, @Resource 애너테이션 뿐만 아니라, **&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;@Component, @Controller, @Repository, @Service 애너테이션이 선언된, 의존성 주입이 가능한 빈의 코드를 스캔하도록 스프링에게 지시&lt;/strong&gt;함!!&lt;/li&gt;
      &lt;li&gt;여러 패키지 정의 가능 : &lt;context:component-scan&gt; 태그에서 쉼표, 세미콜론, 공백을 구분 기호로 사용해 여러 패키지를 정의할 수 있음&lt;/context:component-scan&gt;&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;스캔 범위 제어 가능 : 이 태그에서는 컴포넌트 스캔의 범위와 제외 범위를 지정해 스캔 범위 제어 가능&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;스캔에서 제외할 대상(클래스 또는 인터페이스) 예&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xmlns:context=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/context&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;context:component-scan&lt;/span&gt; 
		&lt;span class=&quot;na&quot;&gt;base-package=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.annotated&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
	  &lt;span class=&quot;nt&quot;&gt;&amp;lt;context:exclude-filter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;assignable&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;expression=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.example.NotAService&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/context:component-scan&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;컴포넌트 스캔(component-scan) 다른 예제&lt;/li&gt;
  &lt;li&gt;예제1) 설정파일로 bean 객체 주입하는 예제&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

      &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;memberDAO&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.spring5.ch3.model.MemberDAO&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sellerDAO&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.spring5.ch3.model.SellerDAO&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;예제2) 예제1)을 컴포넌트 스캔(component-scan)으로 변경&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&lt;/span&gt;
          &lt;span class=&quot;err&quot;&gt;http://www.springframework.org/schema/context&lt;/span&gt;
          &lt;span class=&quot;err&quot;&gt;http://www.springframework.org/schema/context/spring-context.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

      &lt;span class=&quot;nt&quot;&gt;&amp;lt;context:component-scan&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;base-package=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.spring5.ch3.model&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/context:component-scan&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;위의 설정파일 java 예제&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;  &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//설정파일이 어디 있는지를 저장하는 객체&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Resource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ClassPathResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;applicationContext.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;//객체를 생성해주는 factory 객체&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;BeanFactory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;XmlBeanFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;//설정파일에 설정한 &amp;lt;bean&amp;gt; 태그의 id/name을 통해 객체를 받아온다.&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;MemberDAO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memberDAO&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MemberDAO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;memberDao&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;      
    &lt;span class=&quot;nc&quot;&gt;SellerDAO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sellerDAO&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;SellerDAO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sellerDAO&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.3 스프링 컴포넌트 선언하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;스프링에게 이 빈(개발한 클래스)이 다른 빈에 주입될 수 있다는 것을 알려주고, 스프링이 이 빈들을 관리하게 해야 함.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1) xml 설정&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;MessageRenderer가 렌더링할 메시지를 제공하는 MessageProvider에 의존&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// renderered 구현체&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StandardOutMessageRenderer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;messageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot;You must set the property messageProvider of class:&quot;&lt;/span&gt;
                            &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StandardOutMessageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;messageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;messageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;messageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// provider 인터페이스&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;// provider 구현체&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelloWorldMessageProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;app-context-xml.xml&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;htt
       xmlns:xsi=&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xmlns:p=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/p&quot;&lt;/span&gt;
       &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;renderer&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch2.decoupled.StandardOutMessageRenderer&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;p:messageProvider-ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;provider&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;provider&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch2.decoupled.HelloWorldMessageProvider&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;2) 애너테이션 설정 예&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;애너테이션을 사용해 빈 정의를 생성하는 클스&lt;/strong&gt; 예&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//간단한 빈&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@Service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;provider&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelloWorldMessageProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//복잡한 서비스 빈&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@Service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;renderer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StandardOutMessageRenderer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;messageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot;You must set the property messageProvider of class:&quot;&lt;/span&gt;
                            &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StandardOutMessageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;messageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;messageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;messageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;ApplicationContext로부터 빈을 얻는 방법&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DeclareSpringComponents&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;classpath:spring/app-context-xml.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageRenderer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;renderer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
				&lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;messageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;3.5.3.1 자바 구성(Java Configuration) 사용하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;생성된 빈 타입을 드러내도록 클래스를 수정하지 않아도 app-context-xml.xml을 구성 클래스로 교체 가능.&lt;/li&gt;
  &lt;li&gt;이는 애플리케이션에게 필요한 빈 타입이 수정할 수 없는 서드파티 라이브러리의 일부인 경우에 유용
    &lt;ul&gt;
      &lt;li&gt;이러한 구성 클래스에는 &lt;strong&gt;@Configuration 애너테이션&lt;/strong&gt;을 적용!!&lt;/li&gt;
      &lt;li&gt;구성 클래스 내에서는 스프링 IoC 컨테이너가 빈 인스턴스를 만들 때 직접 호출하는 @Bean 애너테이션이 적용된 메서드가 포함돼 있음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;생성되는 빈의 이름이 되는 메서드 이름을 표시하는 예. provider 메소드.
    &lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Configuration&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelloWorldConfiguration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Bean&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HelloWorldMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Bean&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;renderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(){&lt;/span&gt;
      &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;renderer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StandardOutMessageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;renderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;provider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;renderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;AnnotationConfigApplicationContext&lt;/strong&gt;를 사용해 빈 가져오기 (ApplicationContext 구현체 사용)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HelloWorldSpringAnnotated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;nc&quot;&gt;ApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;HelloWorldConfiguration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageRenderer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;renderer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;messageRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;DefaultListableBeanFactory 대신 AnnotationConfigApplicationContext 인스턴스를 생성함&lt;/li&gt;
  &lt;li&gt;AnnotationConfigApplicationContext 클래스는 ApplicationContext 인터페이스를 구현한 클래스로,&lt;/li&gt;
  &lt;li&gt;HelloWorldConfiguration클래스에 정의된 구성을 이용해 스프링의 ApplicationContext를 부트스트랩 할 수 있음&lt;/li&gt;
  &lt;li&gt;빈 정의 구성이 해당 빈 클래스의 일부이므로 구성 클래스가 더 이상 @Bean 애너테이션이 적용된 매소드를 갖고 있지 않아도 됨&lt;/li&gt;
  &lt;li&gt;&amp;lt;context:component-scanning … /&amp;gt;과 동일한 역할을 하는 애너테이션을 구성 클래스에 추가하여 컴포넌트 스캐닝을 할 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.5.3.2 &lt;strong&gt;수정자 주입 사용&lt;/strong&gt;하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;XML을 이용해 수정자 주입을 구성하려면 &lt;bean&gt; 태그 아래에 의존성을 주입할 **&lt;property&gt; 태그**를 지정&lt;/property&gt;&lt;/bean&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;renderer&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch2.decoupled.StandardOutMessageRenderer&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;messageProvider ref=&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;provider&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;이 코드에서 provider 빈이 messageProvider 프로퍼티에 지정되어 있음을 알 수 있음&lt;/li&gt;
  &lt;li&gt;ref 애트리뷰트를 사용하여 프로퍼티에 빈 참조를 지정할 수 있음&lt;/li&gt;
  &lt;li&gt;스프링 2.5버전 이상을 사용한다면 XML 구성 파일에 &lt;strong&gt;p네임 스페이스를 선언하여 의존성 주입&lt;/strong&gt;을 할 수 있음&lt;/li&gt;
  &lt;li&gt;네임스페이스는 XSD 파일에 정의되어 있지 않고 스프링 코어에만 존재함&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;renderer&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch2.decoupled.StandardOutMessageRenderer&quot;&lt;/span&gt; 
          &lt;span class=&quot;na&quot;&gt;p:messageProvider-ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;provider&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;애너테이션을 사용한다면 수정자 메서드에 @Autowired 애너테이션만 추가하여 간단하게 사용할 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@Service(&quot;renderer&quot;)
public class StandardOutMessageRenderer implements MessgeRenderer [
    @Override
    @Autowired
    public void setMessageProvider(MessageProvider provider) {
        this.MessageProvider = provider;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;@Autowired 대신 @Resource(name=”messageProvider”)를 사용해도 같은 결과를 얻을 수 있음&lt;/li&gt;
  &lt;li&gt;@Resource는 @Autowired와 달리 더 세부적인 DI요구에 대응하려는 목적으로 name인자를 제공&lt;/li&gt;
  &lt;li&gt;XML 구성 파일에서 &lt;context:component-scan&gt;&lt;/context:component-scan&gt; 태그를 선언했으므로 스프링은 ApplicationContext를 초기화하는 동안에 @Autowired를 발견하고 필요에 따라 의존성을 주입&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.5.3.3 &lt;strong&gt;생성자 주입 사용&lt;/strong&gt;하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;이제까지는 HelloWorldMessageProvider의 getMessage()를 호출하면 하드코딩된 메시지를 동일하게 반영했음&lt;/li&gt;
  &lt;li&gt;메시지 값을 전달하지 않고서 ConfigurableMessageProvider의 인스턴스를 생성할 수 없기 때문에 이 클래스는 생성자 주입을 하는게 좋음&lt;/li&gt;
  &lt;li&gt;아래의 코드는 ConfigurableMessageProvider 인스턴스를 생성하려는 목적으로 provider 빈을 다시 정의하고 생성자 주입으로 메시지를 주입하는 방법을 보여줌&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;messageProvider&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.xml.ConfigurableMessageProvider&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;constructor-arg&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hi! This is message!&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;property&gt; 태그 대신 &lt;constructor-arg&gt; 사용
&lt;/constructor-arg&gt;&lt;/property&gt;
  &lt;/li&gt;
  &lt;li&gt;다른 빈을 전달하지 않고 문자열만을 전달하기 때문에 ref대신 value 애트리뷰트를 사용하여 생성자 인수의 값을 지정&lt;/li&gt;
  &lt;li&gt;둘 이상의 생성자 인수가 있거나 클래스에 둘 이상의 생성자가 있는 경우에는 인수 인덱스를 지정하는 index애트리뷰트를 각 &lt;constructor-arg&gt;태그에 제공해야 함&lt;/constructor-arg&gt;&lt;/li&gt;
  &lt;li&gt;인자 사이의 혼동을 피하고 스피링이 올바른 생성자를 선택하도록 하려면 다중 인수를 갖는 생성자를 다룰 때마가 항상 index애트리뷰트를 사용하는 것이 좋음&lt;/li&gt;
  &lt;li&gt;
    &lt;constructor-arg&gt;태그는 c네임 스페이스를 사용하여 표현할 수도 있음

&lt;/constructor-arg&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;messageProvider&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.xml.ConfigurableMessageProvider&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;c:message=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hi! This is message!&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;애너테이션을 이용해 생성자 주입을 할 때에도 마찬가지로 대상 빈의 생성자 매소드에 @Autowired 애너테이션을 사용&lt;/li&gt;
  &lt;li&gt;이 방식은 수정자 주입 방식을 대체할 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;provider&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConfigurableMessageProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigurableMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Configurable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;@Value를 사용하여 생성자에 주입할 값을 정의함&lt;/li&gt;
  &lt;li&gt;이런 방식으로 스프링에서는 빈에 값을 주입함&lt;/li&gt;
  &lt;li&gt;간단한 문자열 외에 동적으로 값을 주입하고 싶다면 강력한 기능인 SpEL을 사용할 수 있음&lt;/li&gt;
  &lt;li&gt;그러나 예제와 같이 코드에 값을 하드코딩하는 것은 좋지 않음&lt;/li&gt;
  &lt;li&gt;애너테이션 방식의 DI를 사용하더라도 주입할 값은 외부에 두는 것이 좋음&lt;/li&gt;
  &lt;li&gt;메시지를 외부화 하기 위해서는 아래와 같이 애너테이션 구성파일에서 메시지를 스프링 빈으로 정의해야 함&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;....&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;context:component-scan&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;base-package=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.annotated&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;message&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;java.lang.String&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;c:_0=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;This is message&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Id가 message이고 클래스타입이 java.lang.String인 빈을 정의&lt;/li&gt;
  &lt;li&gt;생성자 주입을 위해 c네임스페이스를 사용해 문자열 값을 설정&lt;/li&gt;
  &lt;li&gt;_0는 생성자 인수에 대한 인덱스를 나타냄&lt;/li&gt;
  &lt;li&gt;이 빈을 사용하면 아래와 같이 @Value를 제거해도 됨&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;provider&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConfigurableMessageProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MessageProvider&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigurableMessageProvider&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;message 빈의 ID가 ConfigurableMessageProvider 클래스의 생성자에 지정된 인자의 이름과 동일하게 선언되었기 때문에 스프링은 @Autowired 애너테이션을 감지하여 값을 생성자 메소드에 주입할 것임&lt;/li&gt;
  &lt;li&gt;인수의 개수도 같은 생성자가 있는 경우 스프링이 어떤 생성자를 사용하여 주입을 해야할지 판단하지 못할 수도 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;bean id=&quot;messageProvider&quot; class=&quot;com.apress.prospring5.ch3.xml.ConfigurableMessageProvider&quot;&gt;
    &lt;constructor-arg type=&quot;int&quot;&gt;
        &lt;value&gt;90&lt;/value&gt;
    &lt;/constructor-arg&gt;
&lt;/bean&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;constructor-arg&gt; 태그에는 스프링이 찾아야 할 인수의 데이터 타입을 지정하는 type 애트리뷰트가 있음
&lt;/constructor-arg&gt;
  &lt;/li&gt;
  &lt;li&gt;애너테이션 방식의 생성자 주입을 사용할 때에는 애너테이션을 대신 생성자 메소드에 직접 적용해 이런 혼란을 피할 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ConstructorConfusion&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConstructorConfusion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;someValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConstructorConfusion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;nd&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConstructorConfusion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;90&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;원하는 생성자 매소드에 @Autowired 애너테이션을 적용하면 스프링은 이 메소드를 사용해 빈 인스턴스를 생성하고 지정한 값을 주입함&lt;/li&gt;
  &lt;li&gt;@Autowired 애너테이션은 생성자 메소드 중에서 하나에만 적용할 수 있음&lt;/li&gt;
  &lt;li&gt;하나 이상의 생성자에 적용하면 스프링은 ApplicationContext를 부트스트랩하는 과정에서 오류를 일으킴&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.5.3.4 &lt;strong&gt;필드 주입 사용&lt;/strong&gt;하기&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;의존성을 생성자나 수정자를 사용하지 않고 필드에 직접 주입함&lt;/li&gt;
  &lt;li&gt;클래스 멤버 변수에 @Autowired 애너테이션을 적용&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;의존성이 필요한 객체의 내부에서만 주입된 의존성을 사용할 경우 사용 하면 개발자가 빈 초기 생성 시 의존성 주입에 사용되는 코드를 작성하지 않아도 되므로 실용적임&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;예제 3-40) 필드 주입을 이용한 빈 클래스([filed-injection] Singer.java)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;singer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;singer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Inspiration&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inspirationBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;...&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inspirationBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Inspiration 필드는 private이지만 스프링 IoC 컨테이너가 의존성을 주입하는 것에는 문제없음&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;스프링 컨테이너가 리플렉션을 이용해 필요한 의존성을 주입하기 때문&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;다음 예제에서 Inspiration 클래스 코드를 확인. 이 빈은 String 타입의 멤버 변수를 가진 단순한 빈.&lt;/li&gt;
  &lt;li&gt;예제 3.41) String 타입 멤버 변수를 가진 빈 클래스(filed-injection] Inspiration.java)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.apress.prospring5.ch3.annotated&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.beans.factory.annotation.Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Inspiration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;I can keep the door cracked open, to let light through&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Inspiration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;For all my running, I can understand&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lyric&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getLyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setLyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lyric&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;아래 코드는 스프링 IoC컨테이너가 생성할 빈의 정의를 찾을 수 있도록 컴포넌트 스캔 설정을 활성화하는 구성&lt;/li&gt;
  &lt;li&gt;예제 3-42) 컴포넌트 스캐닝 설정을 한 구성 파일(filed-injection] app-context.xml)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;....&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;context:component-scan&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;base-package=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.annotated&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;스프링 IoC 컨테이너는 Inspiration타입의 빈을 발견하면 singer 빈의 inspirationBean 멤버에 해당 빈을 주입할 것&lt;/li&gt;
  &lt;li&gt;그래서 다음 코드에 나와 있는 예제를 실행하면 “For all my running, I can understand”이라는 메시지가 콘솔에 출력됨&lt;/li&gt;
  &lt;li&gt;예제 3-43) 필드 주입 테스트 실행을 위한 FieldInjection 클래스([filed-injection] FieldInjection.java)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.apress.prospring5.ch3.annotated&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;org.springframework.context.support.GenericXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FieldInjection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

		&lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;classpath:spring/app-context.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

		&lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;singerBean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;singerBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

		&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;하지만 필드 주입은 여러 단점이 있어서 일반적으로 사용을 권장하지 안음!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;필드 주입의 단점&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;의존성을 추가하기 쉽지만 단일 책임 원칙을 위반하지 않도록 주의해야함
        &lt;ul&gt;
          &lt;li&gt;더 많은 의존성이 생기면 클래스에 대한 책임이 커지므로 리팩토링 시에 관심사를 분리하기 어려움&lt;/li&gt;
          &lt;li&gt;클래스가 비대해지는 상황은 생성자나 수정자 주입을 사용하면 쉽게 알 수 있지만 필드 주입은 알아채기 어려움&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;의존성 주입의 책임은 스프링 컨테이너에게 있지만, 클래스는 public 인터페이스의 매소드나 생성자를 이용해 필요한 의존성 타입을 명확하게 전달해야함
        &lt;ul&gt;
          &lt;li&gt;그러나 필드 주입을 사용하면 어떤 타입의 의존성이 실제 필요한지, 의존성이 필수인지 여부가 명확하지 않을 수도 있음&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;필드 주입은 final 필드에 사용할 수 없음. 이 타입 필드는 오직 생성자 주입만을 사용하여 초기화 할 수 있음&lt;/li&gt;
      &lt;li&gt;필드 주입은 의존성을 수동으로 주입해야하므로 테스트 코드를 작성하기 어려움&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.3.5 &lt;strong&gt;주입 인자 사용&lt;/strong&gt;하기&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;스프링은 다른 컴포넌트나 단순 값 외에 자바 컬렉션, 외부에 정의된 프로퍼티, 다른 팩터의 빈을 주입할 수 있도록 많은 옵션의 주입인자를 지원함&lt;/li&gt;
  &lt;li&gt;수정자 주입이나 생성자 주입 시에 &lt;property&gt;, &lt;constructor-arg&gt; 태그의 관련 태그들을 사용해 다양한 타입의 주입 인자를 사용할 수 있음&lt;/constructor-arg&gt;&lt;/property&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.3.7 &lt;strong&gt;SpEL을 사용&lt;/strong&gt;해 값 주입하기&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;스프링 표현식 언어(Spring Expression Language)&lt;/li&gt;
  &lt;li&gt;SpEL을 사용하면 표현식을 동적으로 평가하여 그 결과를 스프링의 ApplicationContext 내에서 사용할 수 있음&lt;/li&gt;
  &lt;li&gt;표현식 평가 결과는 스프링 빈에 주입될 수 있음&lt;/li&gt;
  &lt;li&gt;다른 빈의 프로퍼티를 참조할 때는 #{classname.참조할 변수}처럼 SpEL을 사용함&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;baen&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;injectionSimpleSpel&quot;&lt;/span&gt;
     &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.xml.InjectionSimpleSpel&quot;&lt;/span&gt;
     &lt;span class=&quot;na&quot;&gt;p:name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#{injectSimpleConfig.name}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt; 
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;injectionSimpleSpel 빈을 주입받을 클래스 , injectSimpleConfig 빈의 값을 정의한 클래스(빈을 주입한 클래스)&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;injectSimpleConfig에서 정의된 값을 xml을 통해 injectionSimpleSpel에 주입함&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;애너테이션 방식으로 값을 주입하려면 value 애너테이션을 SpEL 표현식과 함께 사용하도록 변경&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Service&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;InjectSimpleSpel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;#{injectSimpleConfig.name}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;@Servicedhk @Component는 동일한 효과의 애너테이션&lt;/li&gt;
  &lt;li&gt;@Service는 @Component의 특수한 형태이며, @Service가 사용된 클래스는 애플리케이션 내의 다른 레이어에게 비즈니스 서비스를 제공하고 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.5.3.8 &lt;strong&gt;같은 XML구성 내에세 빈 주입&lt;/strong&gt; 받기&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ref 태그를 사용하면 특정 빈을 다른빈에 주입할 수 있름&lt;/li&gt;
  &lt;li&gt;어떤 빈을 다른 빈에 주입하도록 스프링 구성을 하려면, 먼저 두 개의 빈에 대해 각각 구성을 해야함&lt;/li&gt;
  &lt;li&gt;하나의 빈은 주입이 되는 빈이고, 다른 하나의 빈은 주입을 받는 대상 빈&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;baen&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;oracle&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;wisdom&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.BookwormOracle&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt; 
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;injectRef&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.xml.InjectRef&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;oracle&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bean=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;oracle&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;주입되는 빈의 타입이 대상 빈에 정의된 타입과 정확히 같을 필요는 없음. 타입은 서로 호환되기만 하면 됨&lt;/li&gt;
  &lt;li&gt;호환된다는 것은 대상 빈에 선언된 타입이 인터페이스라면 주입된 타입이 이 인터페이스의 구현체여야함&lt;/li&gt;
  &lt;li&gt;선언된 타입이 클래스라면 주입된 타입은 동일한 타입이거나 해당 타입을 상속한 타입이어야 함&lt;/li&gt;
  &lt;li&gt;주입할 빈의 ID는 &lt;ref&gt;태그의 local애트리뷰트를 사용해 지정할 수 있음&lt;/ref&gt;&lt;/li&gt;
  &lt;li&gt;local애트리뷰트를 사용하면 &lt;ref&gt; 태그는 빈의 별칭을 찾지 않고 ID만 보며, 빈정의는 같은 XML 구성 차일에 존재해야함&lt;/ref&gt;&lt;/li&gt;
  &lt;li&gt;다른 이름으로 빈을 주입하거나 다른 XML 구성 파일에 선언된 빈을 가져오려면 local애트리뷰트 대신 &lt;ref&gt;태그의 bean 애트리뷰트를 사용해야함&lt;/ref&gt;&lt;/li&gt;
  &lt;li&gt;위의 예제를 보면 name 애트리뷰트를 사용해 oracle 빈에 별칭을 부여하고, 이 별칭을 &lt;ref&gt; 태그의 bean 애트리뷰트에 지정해 oracle 빈을 injectRef 빈에 주입&lt;/ref&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.3.9 &lt;strong&gt;주입과 ApplicationContext의 중첩&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;지금까지 본 예시는 우리가 주입한 빈은 주입 대상 빈과 동일한 ApplicationContext(즉, 동인한 BeanFactory)에 있었음&lt;/li&gt;
  &lt;li&gt;스프링은 어떤 컨텍스트가 다른 컨텍스트의 부모가 될 수 있도록 ApplicationContext의 계층 구조도 지원함&lt;/li&gt;
  &lt;li&gt;ApplicationContext를 중첩할 수 있는 기능을 통해 스프링은 구성파일을 서로 다른 여러 파일로 나눌 수 있게 함&lt;/li&gt;
  &lt;li&gt;스프링은 ApplicationContext 인스턴스를 중첩 시킬 때, 부모 컨텍스트에 있는 참조 빈을 자식 컨텍스트에 있는 빈처럼 사용할 수 있게함&lt;/li&gt;
  &lt;li&gt;GenericXmlApplicationContext를 사용하면 간단하게 중첩시킬 수 있음&lt;/li&gt;
  &lt;li&gt;특정 GenericXmlApplicationContext를 다른 GenericXmlApplicationContext 클래스 안에 중첩시키려면 자식 ApplicationContext에서 setParent() 메소드를 호출하면 됨&lt;/li&gt;
  &lt;li&gt;자식 ApplicaationContext의 구성 파일에서 부모 ApplicationContext의 빈을 참조하는 일은 자식 ApplicationContext에 동일한 이름을 가진 빈이 없는 한 동일함&lt;/li&gt;
  &lt;li&gt;이 경우 ref요소의 bean애트리뷰트를 parent로 바꾸기만 하면 됨&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HierarchicalAppContextUsage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;classpath:spring/parent-context.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

		&lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;classpath:spring/child-context.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setParent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

		&lt;span class=&quot;nc&quot;&gt;Song&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;song1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Song&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;song1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Song&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;song2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Song&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;song2&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;Song&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;song3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Song&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;song3&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

		&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;parent 컨텍스트로부터: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;song1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTitle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;child 컨텍스트로부터: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;song2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTitle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
		&lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;parent 컨텍스트로부터: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;song3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTitle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;

		&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Song&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setTitle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getTitle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;child-context.xml&lt;/p&gt;
&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;song1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.Song&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;p:title-ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;parentTitle&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;song2&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.Song&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;p:title-ref=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;childTitle&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;song3&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.Song&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;parent=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;childTitle&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;childTitle&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.Song&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;c:_0=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;해당 값이 없습니다.&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;song1 빈은 ref 애트리뷰트를 사용해 parentTitle이라는 빈을 참조함
    &lt;ul&gt;
      &lt;li&gt;parentTitle 빈은 부모 BeanFactory에만 존재하므로 Song1은 parentTitle 빈에 대한 참조를 받음&lt;/li&gt;
      &lt;li&gt;빈 구성시 애트리뷰트로 자식 ApplicationContext와 부모 AC의 빈을 참조할 수 있음
        &lt;ul&gt;
          &lt;li&gt;때문에 빈을 투명하게 탐조할 수 있어서 애플리케이션이 커지면 구성 파일간에 빈을 이동할 수 있음&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;local 애트리뷰트를 사용해 부모 AC의 빈을 참조할 수 없음
        &lt;ul&gt;
          &lt;li&gt;XML 파서는 local애트리뷰트의 값이 동일한 파일에 유효한 요소로 존재하는지 확인하므오 부모 컨텍스트의     빈을 참조하지 않도록 함&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;song2 빈은 ref 애트리뷰트를 사용해 childTitle을 참조함
    &lt;ul&gt;
      &lt;li&gt;song2빈이 참조하는 childTitle빈이 양쪽 AC에 정의되어 있으므로 song2빈은 자신의 AC에서 childTitle에 대한 참조를 받음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;song3 빈은 &lt;ref&gt;태그를 사용해 부모 AC로부터 직접 childTitle을 참조힘
&lt;/ref&gt;    &lt;ul&gt;
      &lt;li&gt;
        &lt;ref&gt; 태그의 parent 애트리뷰트를 사용하기 때문에 자식 AC에 선언된 childTitle 인스턴스는 완전히 무시됨
&lt;/ref&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;p네임스페이스는 편리한 단축 표현을 제공하지만 부모 빈을 참조하려고 property태그를 사용하는 것과 같은 모든 기능을 제공하지는 않음&lt;/li&gt;
  &lt;li&gt;꼭 필요한 경우가 아니라면 예시처럼 섞어서 사용하지 않는 것이 좋음&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.3.10 &lt;strong&gt;컬렉션 주입&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;List, Map, Set, Properties 인스턴스를 나타내는 &lt;list&gt;, &amp;lt;map&amp;gt;, &lt;set&gt;, &lt;props&gt;태그 중 하나를 선택하고 다른 주입 방식 처럼 개별 항목을 전달&lt;/props&gt;&lt;/set&gt;&lt;/list&gt;&lt;/li&gt;
  &lt;li&gt;Properties 클래스는 String 프로퍼티 값만을 허용하기 때문에 &lt;props&gt;태그는 String만 값으로 전달할 수 있음&lt;/props&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;list&gt;, &lt;map&gt;, &lt;set&gt;을 사용해 프로퍼티에 주입할 때에는 원하는 태그를 사용할 수 있으며, 다른 컬렉션 태그도 함께 사용할 수 있음

&lt;/set&gt;&lt;/map&gt;&lt;/list&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;map&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;map&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;entry&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;key=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;someValue&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;HelloWorld&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/entry&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;entry&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;key=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;someBean&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bean=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lyricHolder&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/entry&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;map&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;map의 각 항목은 &lt;entry&gt;태그를 사용해 지정하는데, 이 항목은 문자열 키와 엔트리 값을 가짐&lt;/entry&gt;&lt;/li&gt;
  &lt;li&gt;이 엔트리 값은 프로퍼티에 별도로 주입할 수 있는값이 될 수 있음&lt;/li&gt;
  &lt;li&gt;
    &lt;map&gt; 요소에는 &lt;value&gt; 및 &lt;ref&gt; 요소 대신 value와 value-ref 애트리뷰트를 사용하여 보다 간결하게 사용 가능

&lt;/ref&gt;&lt;/value&gt;&lt;/map&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;set&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;set&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;HelloWorld&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bean=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lyricHolder&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/set&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;list&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;list&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;HelloWorld&lt;span class=&quot;nt&quot;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ref&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bean=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lyricHolder&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/list&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;list&gt;와 &lt;set&gt; 태그는 동일한 방식으로 동작함
&lt;/set&gt;&lt;/list&gt;
  &lt;/li&gt;
  &lt;li&gt;값 하나를 프로퍼티에 주입하는데 사용되는 &lt;value&gt;나 &lt;ref&gt;와 같은 태그 중 하나를 사용해 각각의 요소를 지정&lt;/ref&gt;&lt;/value&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;list&gt;, &lt;map&gt;, &lt;set&gt; 태그에 컬렉션 엔트리 값 하나를 지정할 때, 컬렉션이 아닌 프로퍼티 값을 설정하는 태그를 사용할 수 있음
&lt;/set&gt;&lt;/map&gt;&lt;/list&gt;
  &lt;/li&gt;
  &lt;li&gt;이는 원시값 컬렉션만을 빈에 주입할 수 있는 것이 아닌 빈으로 이워진 컬렉션이나 다른 컬렉션으로 이뤄진 컬렉션도 필요한 곳에 주입할 수 있음&lt;/li&gt;
  &lt;li&gt;이 기능을 사용하면 애플리케이션을 모듈화하기가 쉽고 서로 다른 애플리케이션 로직의 주요 부분을 사용자가 선택한 구현체로 제공할 수 있음&lt;/li&gt;
  &lt;li&gt;XML 구성 외에 애노테이션을 사용해 컬렉션을 주입할 수 있지만 유지보수를 쉽게 하려면 컬렉션 값을 외부 구성 파일로 관리하는 것이 좋음&lt;/li&gt;
  &lt;li&gt;컬렉션 타입을 주입할 때에는 빈 이름을 지정할 수 있도록 지원하는 @Resource 애너테이션을 사용해 빈 이름을 지정하고, 스프링에 명시적으로 의존성을 알맞게 주입하도록 알려줘야함&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.4 &lt;strong&gt;메소드 주입 사용&lt;/strong&gt;하기&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;자주 사용하지는 않음&lt;/li&gt;
  &lt;li&gt;loosely related 형태인 룩업 메소드 주입과 메소드 대체 방식 제공&lt;/li&gt;
  &lt;li&gt;메소드 대체를 사용하면 원래 소스 코드를 변경하지 않고 임의로 메소드 구현을 변경할 수 있음&lt;/li&gt;
  &lt;li&gt;이 두가지 기능을 제공하기 위해 스프링은 CGLIB의 동적 바이트 코드 확장 기능을 사용&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.4.1 &lt;strong&gt;룩업 메소드 주입&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;싱글턴 빈이 비싱글턴 빈에 의존하는 상황과 같이 어떤 빈이 다른 라이츠 사이클을 가진 빈에 의존할 때 발생하는 문제를 극복하기 위해 스프링 1.1버전에 추가&lt;/li&gt;
  &lt;li&gt;ApplicationContextAware 인터페이스를 구현하면 싱글턴 빈은 ApplicationContext 인스턴스를 사용해서 필요할 때마다 비싱글턴 의존성의 새 인스턴스를 룩업할 수 있음&lt;/li&gt;
  &lt;li&gt;룩업 메소드 주입을 이용하면 별도의 스프링 인터페이스를 구현하지 않아도 싱글턴 빈이 비싱글턴 빈 의존성을 필요로 할 때마다  선언하여 비싱글턴 빈의 새로운 인스턴스를 얻을 수 있게 해줌&lt;/li&gt;
  &lt;li&gt;비싱글턴 빈의 인스턴스를 반환하는 룩업 메소드를 싱글턴 빈에 선언함으로써 동작&lt;/li&gt;
  &lt;li&gt;애플리케이션에서 싱글턴에 대한 참조를 얻을 때, 스프링이 구현해 둔 룩업 메소드를 사용해서 동적으로 생성된 서브 클래스에 대한 참조를 받음&lt;/li&gt;
  &lt;li&gt;일반적으로는 룩업 메소드를 구현없이 정의만하므로 구현클래스를 abstract으로 선언함&lt;/li&gt;
  &lt;li&gt;abstract로 선언하면 메소드 주입 구성을 잊어버렸을 때 스프링이 수정한 서브 클래스의 메소드가 아닌 텅 빈 메소드에서 가져온 빈 클래스를 직접 사용해 발생하는 문제를 방지함&lt;/li&gt;
  &lt;li&gt;abstract LookupBean은 &lt;lookup-method&gt; 태그를 사용해 룩업 메소드를 구성 해야 함&lt;/lookup-method&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;lookup-method&gt; 태그의 name 애트리뷰트는 빈이 오버라이드해야 하는 메소드 이름을 스프링에 알려줌
&lt;/lookup-method&gt;
  &lt;/li&gt;
  &lt;li&gt;이 메소드는 인수를 받지 말아야 하며, 반환 타입은 메소드가 반환하는 빈의 타입이어야 함&lt;/li&gt;
  &lt;li&gt;bean 애트리뷰트는 룩업 메소드가 반환해야 하는 빈이 무엇인지 스프링에 알려줌&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LookupDemo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;classpath:spring/app-context-xml.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;DemoBean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;abstractBean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abstractLookupBean&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DemoBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;DemoBean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;standardBean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;standardLookupBean&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DemoBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;displayInfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;abstractLookupBean&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;abstractBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;displayInfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;standardLookupBean&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;standardBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;displayInfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;beanName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DemoBean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;singer1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMySinger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;singer2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMySinger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// singer 타입의 로컬 변수 두 개 생성하고 전달된 빈에서 getMySinger()를 호출해 각 값을 할당&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;beanName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;]: Singer 인스턴스는 같은가? &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;singer1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;singer2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 두 참조 객체가 같은 객체를 가리키는지 확인&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;StopWatch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stopWatch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StopWatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;stopWatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lookupDemo&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;singer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMySinger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;stopWatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;100000번을 얻어오는데 걸리는 시간 : &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stopWatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTotalTimeMillis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; ms&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;GenericXmlApplicationContext로 부터 abstractLookupBean과 standardLookupBean이 룩업되고, 각 참조가 displayInfo() 메소드에 전달됨&lt;/li&gt;
  &lt;li&gt;추상 클래스의 인스턴스 생성은 룩업 메소드 주입을 이용할 때만 지원됨&lt;/li&gt;
  &lt;li&gt;메소드 룩업을 사용하면 스프링이 CGLIB를 사용해 메소드를 동적으로 재정의 하는 AbstractLookupDemoBean클래스의 하위 클래스를 생성&lt;/li&gt;
  &lt;li&gt;abstractLookupBean 빈은 getMySinger()를 호출할 때마다 Singer의 새 인스턴스를 검색해야 하므로 참조가 동일하지 X&lt;/li&gt;
  &lt;li&gt;standardLookupBean의 경우 Singer의 단일 인스턴스가 수정자 주입을 통해 빈으로 전달되어 저장되며 getMySinger()를 호출할 때마다 해당 인스턴스가 반환되므로 두 참조가 동일해야함&lt;/li&gt;
  &lt;li&gt;stopWatch 클래스는 스프링에서 사용할 수 있는 유틸리티 클래스로 간단한 성능을 테스트해야할 때와 애플리케이션 테스트를 할때 유용&lt;/li&gt;
  &lt;li&gt;standardLookupBean이 속도가 더 빠름&lt;/li&gt;
  &lt;li&gt;애너테이션으로 할 경우 getMySinger() 메소드에 는 구현 내용을 비워두고 Singer 빈의 이름을 인수로 받는 @Lookup 애너테이션을 적용함&lt;/li&gt;
  &lt;li&gt;메소드의 내용은 동적으로 생성된하위 클래스에서 재정의됨&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.5.4.2 룩업 메소드 주입 시 고려사항&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;룩업 메소드 주입은 다른 라이프 사이클을 가진 두 빈을 사용해 작업을 하는 경우에 사용&lt;/li&gt;
  &lt;li&gt;하나의 공통 의존성을 공유하는 세 개의 싱글턴을 생각해 보면 비싱글턴으로 의존성을 생성할 수도 있지만, 동일한 인스턴스를 사용하더라도 문제가 없을 경우 수정자 주입이 이상적이며, 룩업 메소드 주입은 불필요한 오버헤드를 발생시킬 뿐임&lt;/li&gt;
  &lt;li&gt;일반적으로 IoC 목적으로만 사용되는 불필요한 정의로 비즈니스 인터페이스를 오염시키지 말아야 함&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.4.3 메소드 대체&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;지금까지는 협력 객체를 빈에 제공하는데 온전히 주입만을 사용&lt;/li&gt;
  &lt;li&gt;메소드 대체를 사용하면 수정 중인 빈의 소스를 변경하지 않고 임의로 모든 메소드 구현체를 바꿀 수 있음&lt;/li&gt;
  &lt;li&gt;내부적으로 빈 클래스의 서브 클래스를 동적으로 생성하면 메소드를 대체할 수 있음&lt;/li&gt;
  &lt;li&gt;CGLIB를 사용해 원래 메소드의 호출을 MethodReplacer 인터페이스를 구현한 다른 빈에 대한 호출로 리디렉션할 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.4.4 메소드 대체를 사용할 때&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;동일 타입의 모든 빈이 아닌 단일 빈에 대한 특정 메소드만 대체하려는 경우에 유용&lt;/li&gt;
  &lt;li&gt;런타임 바이트 코드 향상에 의존하기 보다는 표준 자바 메커니즘을 사용해 메소드를 대체하는 것이 더 바람직함&lt;/li&gt;
  &lt;li&gt;애플리케이션 일부에서 메소드 대체를 사용하려는 경우에는 메소드나 오버로드된 메소드 그룹마다 MethodReplacer를 하나만 사용하는 것을 권장함&lt;/li&gt;
  &lt;li&gt;사용시 성능이 걱정된다면 Boolean타입 애트리뷰트를 MethodReplacer에 추가하면 의존성 주입을 이용해 검사 여부를 켜고 끌 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.5 &lt;strong&gt;빈 명명 규칙&lt;/strong&gt; 이해하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;모든 빈은 ApplicationContext 내에서 고유한 하나 이상의 이름을 가져야 함&lt;/li&gt;
  &lt;li&gt;
    &lt;bean&gt; 태그에 id 애트리뷰트의 값을 지정하면 이 값이 이름으로 사용됨
&lt;/bean&gt;
  &lt;/li&gt;
  &lt;li&gt;id 애트리뷰트에 값이 지정되지 않으면 스프링은 name 애트리뷰트를 찾는데, name 애트리뷰트 값이 여러 개 정의되어 있다면 그 중 첫 번째 이름을 사용&lt;/li&gt;
  &lt;li&gt;id와 name 애트리뷰트가 모두 지정되지 않으면 스프링은 빈의 클래스 이름을 빈 이름으로 사용(피하는게 좋음)
    &lt;ul&gt;
      &lt;li&gt;동일한 타입의 여러 빈을 정의할 수 없으므로 유연하지 않음&lt;/li&gt;
      &lt;li&gt;고유한 이름을 지정하면 사용하던 스프링의 동작 방식이 나중에 달라지더라고 애플리케이션은 계속 잘 동작할 것임&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;id나 name이 없는 같은 타입의 빈이 여러 개 선언되면 스프링은 ApplicationContext를 초기화 하는 과정에서 해당 타입의 빈을 주입할 때 예외를 던짐&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.5.1 &lt;strong&gt;빈 이름 별칭&lt;/strong&gt; 짓기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;스프링에서는 빈이 여러 개의 이름을 가질 수 있음&lt;/li&gt;
  &lt;li&gt;빈에 여러 이름 지정하기 : name 애트리뷰트에 공백, 쉼표, 세미콜론 등으로 구분해 이름의 목록을 지정하면 됨&lt;/li&gt;
  &lt;li&gt;name 애트리뷰트는 id 애트리뷰트 개신에 사용될 수도 있고, id 애트리뷰트와 함께 사용될 수도 있음&lt;/li&gt;
  &lt;li&gt;name들에 대한 별칭을 정의할 때 &lt;alias&gt;태그를 사용할 수 있음&lt;/alias&gt;&lt;/li&gt;
  &lt;li&gt;ApplicationContext.getAliases(String)을 호출하며 빈의 이름이나 id를 전달해 빈의 별칭 목록을 검색할 수 있음
    &lt;ul&gt;
      &lt;li&gt;이렇게 하면 지정한 이름 외에 별칭 목록이 String 배열로 반환됨&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;name과 id 애트리뷰트 값은 스프링 IoC에 의해 다르게 다루어짐&lt;/li&gt;
&lt;/ul&gt;

&lt;bean name=&quot;jon &quot; class=&quot;java.lang.String&quot; /&gt;

&lt;bane id=&quot;jon johnny,jonathan;jim&quot; class=&quot;java.lang.String&quot; /&gt;

&lt;ul&gt;
  &lt;li&gt;name은 지정한 별칭을 제외하고 나머지 별칭이 문자열 배열로 반환됨
    &lt;ul&gt;
      &lt;li&gt;id : jon / 별칭: [johnny,jonathan,jim]&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;id는 전체 문자열은 빈에 대한 고유한 식별자가 됨
    &lt;ul&gt;
      &lt;li&gt;id : jon,johnny,jonathan,jim / 별칭 : []&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;어떤 빈에 주입할 다른 빈이 많을 경우에는 같은 이름을 사용해 해당 빈에 접근하는 것이 더 나음&lt;/li&gt;
  &lt;li&gt;하지만 애플리케이션이 제품으로써 완성된 후 유지보수로 인해 수정하다 보면 빈 이름 별칭을 만드는 것이 유용&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.5.2 &lt;strong&gt;애너테이션 구성을 이용&lt;/strong&gt;한 빈 명명 규칙&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;애너테이션으로 빈을 선언하는 것은 XML을 사용할 때와는 다름&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hey~~~~!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setLyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ggggggggg&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lyric&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;이 클래스에는 @Component 애너테이션을 적용한 Singer 타입의 싱글턴 빈 선언이 포함돼 있음&lt;/li&gt;
  &lt;li&gt;@Component 애너테이션에는 인수가 없기 때문에 스프링 IoC 컨테이너가 빈에 대한 고유한 식별자를 결정&lt;/li&gt;
  &lt;li&gt;이 경우에는 클래스 자체로 빈을 명명하고 첫 번째 문자를 내림차순으로 처리하는 것 -&amp;gt; Singer이름이 빈 이름이 됨&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;johnMayer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hey~~~~!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setLyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ggggggggg&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lyric&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lyric&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;위 방법으로 별칭을 선언하고자 할 때 @Component 애너테이션의 인수가 빈의 고유 식별자가 되므로 불가능&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AliasConfigDemo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Configuration&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AliasBeanConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;nd&quot;&gt;@Bean&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;@Baen 애너테이션에 인수가 제공되지 않으면 빈의 고유 식별자인 id로 메소드 이름이 사용됨&lt;/li&gt;
  &lt;li&gt;별칭을 선언하려면 @Bean 애너테이션의 name 어트리뷰트를 사용&lt;/li&gt;
  &lt;li&gt;이 애트리뷰트의 값이 별칭 지정 시에 사용할 수 있는 구분 기호(공백, 쉼표, 세미콜론)을 포함하는 문자열이라면 이 문자열이 빈의 id가 됨&lt;/li&gt;
  &lt;li&gt;값이 문자열 배열이면 첫 번쨰 값은 id가 되고, 다른 값은 별칭이 됨&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AliasConfigDemo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Configuration&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AliasBeanConfig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;nd&quot;&gt;@Bean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;={&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;johnMayer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;john&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;jonathan&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;jonny&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
           &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;스프링 4.2dptj @AliasFor 애너테이션이 도입됨&lt;/li&gt;
  &lt;li&gt;이 애너테이션은 애너테이션 애트리뷰트에 대한 별칭을 선언하는 데 사용됨&lt;/li&gt;
  &lt;li&gt;대부분의 스프링 애너테이션은 이 애너테이션을 사용함&lt;/li&gt;
  &lt;li&gt;메타 애너테이션 애트리뷰트에 대한 별칭을 선언할 수 있음&lt;/li&gt;
  &lt;li&gt;그러나 스테에오 타입 애너테이션에 사용할 수 없음
    &lt;ul&gt;
      &lt;li&gt;@AliasFor가 생겨나기 수년 전부터 스테레오 타입 애너테이션의 value 애트리뷰트를 특수하게 처리했기 때문&lt;/li&gt;
      &lt;li&gt;그래서 스테에오 타입 애너테이션에서 value 애트리뷰트에 별팅을 지정하는 코드를 작성해도 컴파일 오류는 없을 수 있지만 별칭에 제공된 인수는 무너짐&lt;/li&gt;
      &lt;li&gt;@Qualifier 애너테이션에도 동일한 제약이 적용됨&lt;/li&gt;
      &lt;li&gt;스테레오 타입 애너테이션 : @Component과 @Service, @Repository, @Controller처럼 @Component 애너테이션의 특수한 형태인 애너테이션&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.6 &lt;strong&gt;빈 생성 방식&lt;/strong&gt; 이해하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;기본적으로 스프링의 모든 빈은 싱글톤&lt;/strong&gt;임!!&lt;/li&gt;
  &lt;li&gt;스프링은 빈의 단일 인스턴스를 유지하고 관리하며, 모든 의존객체는 동일한 인스턴스를 사용하고 ApplicationContext.getBean()에 대한 모든 호출은 동일한 인스턴스를 반환&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;싱글톤은 애플리케이션 내에 단일 인스턴스를 갖는 객체(싱글톤)와 싱글톤 디자인 패턴을 나타내려는 목적(싱글톤패턴)으로 상호 교환적으로 사용&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;NonSingleton 예제 코드&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NonSingletonDemo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GenericXmlApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;//ctx.load(&quot;classpath:spring/app-context-xml.xml&quot;);&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;classpath:spring/app-context-annotated.xml&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;refresh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        
          &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;singer1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nonSingleton&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;singer2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nonSingleton&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        
          &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;식별자가 동일한가?: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;singer1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;singer2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
          &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;값이 동일한가?: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;singer1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;singer2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
          &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;singer1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;singer2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

          &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Singleton 예제 코드&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singleton&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singleton&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singleton&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Singleton&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(){&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// needed so developers cannot instantiate this class directly&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;위의 코드는 애플리케이션 전체에서 클래스의 단일 인스턴스를 유지 관리하고 접근하도록하는 목표는 달성했지만, 결합도가 증가&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;싱글톤 패턴&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;두 개의 패턴이 하나로 합쳐진 것&lt;/li&gt;
      &lt;li&gt;클래스가 단일 인스턴스로 동작하도록 관리하는 것&lt;/li&gt;
      &lt;li&gt;인터페이스를 완전히 사용할 수 없는 객체 룩업을 위한 패턴&lt;/li&gt;
      &lt;li&gt;cf.) 어떤 클래스에서 호출해도 하나의 특정 인스턴스만 호출됨. 공통된 오브젝트를 사용해야 하는 상황에서 특정한 하나의 오브젝트만 사용하게 해줌.(ex.) DBConnectionPool)
        &lt;ul&gt;
          &lt;li&gt;구현방법
            &lt;ul&gt;
              &lt;li&gt;1) 생성자를 private으로으로 선언: 외부에서 클래스의 오브젝트를 생성할 수 없게됨.&lt;/li&gt;
              &lt;li&gt;2) 참조는 static으로 정의: 어느 영역에서든 접근이 가능하도록 함.&lt;/li&gt;
              &lt;li&gt;이렇게 하면 클래스가 classloader에 의해 단 한번만 인스턴스화 되는 것을 이용하여 구현.&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;싱글톤 패턴의 단점
    &lt;ul&gt;
      &lt;li&gt;싱글톤 패턴을 사용하면 싱글톤 인스턴스를 필요로 하는 대부분의 객체가 싱글톤 객체에 직접 접근하기 때문에 임의로 구현을 변경하기 어려움&lt;/li&gt;
      &lt;li&gt;다행히도 스프링을 사용하면 싱글톤 디자인 패턴을 사용하지 않고도 싱글톤 인스턴스 생성 모델을 활용할 수 있음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;스프링의 모든 빈은 기본적으로 싱글톤 인스턴스로 생성&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;스프링은 해당 빈에 대한 모든 요청을 동일한 인스턴스를 사용하여 수행함&lt;/li&gt;
  &lt;li&gt;스프링의 인스턴스 생성방식은 애플리케이션 코드에는 아무런 영향을 주지 않으므로 스프링에서는 싱글톤 뿐만 아니라 모든 인스턴스 생성 방식을 사용할 수 있음&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;싱글톤이 멀티 스레드 접근에 적합하지 않다고 생각된다면, 애플리케이션 코드에 영향을 주지 않으면서 싱글톤이 아닌 타입으로 변경할 수 있음&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;아래 코드는 싱글톤에서 비싱글톤으로 바꾸는 예제&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;beans&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:c=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/c&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;bean&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nonSingleton&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;com.apress.prospring5.ch3.annotated.Singer&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;scope=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;prototype&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;c:_0=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John Mayer&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;nonSingleton&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@Scope&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;prototype&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;unknown&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;John Mayer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;컴포넌트 스캔이 활성화되어 있지 않으면 클래스의 애너테이션은 무시&lt;/li&gt;
  &lt;li&gt;스프링은 스코프의 기본값을 싱글톤으로 설정&lt;/li&gt;
  &lt;li&gt;프로토타입 스코프를 지정하면 스프링은 애플리케이션이 빈 인스턴스를 요청할 때마다 새 인스턴스를 생성&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.6.1 &lt;strong&gt;인스턴스 생성 방식 선택&lt;/strong&gt;하기&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;싱글톤이 유리한 경우&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;상태가 없는 공유 객체
    &lt;ul&gt;
      &lt;li&gt;상태를 유지하지 않으며, 많은 의존 객체를 가지는 경우&lt;/li&gt;
      &lt;li&gt;상태가 없으면 동기화할 필요가 없어 의존 객체가 로직 처리를 위해 빈을 사용할 때마다 새 인스턴스를 생성할 필요가 없음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;읽기 전용 상태를 갖는 공유 객체
    &lt;ul&gt;
      &lt;li&gt;여전히 동기화가 필요하지 않으므로 빈을 요청할 때마다 인스턴스를 생성하면 불필요한 오버헤드만 늘어남&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;공유상태를 갖는 공유 객체
    &lt;ul&gt;
      &lt;li&gt;공유되어야 하는 상태를 가진 빈이 있다면 싱글턴이 이상적인 선택임&lt;/li&gt;
      &lt;li&gt;이 때에는 쓰기에 대한 동기화가 가능한 한 최소한으로 이루어져야 함&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;쓰기 가능 상태를 갖는 대용량 처리(High-throughput) 객체
    &lt;ul&gt;
      &lt;li&gt;애플리케이션에서 많이 사용되는 빈이 있다면 싱글톤을 유지하고, 모든 쓰기 접근을 빈 상태에 동기화하면 수백 개의 인스턴스를 끊임없이 생성하는 것보다 나은 성능을 얻을 수 있음&lt;/li&gt;
      &lt;li&gt;빈에 이런 방식을 사용할 때에는 일관성을 희생시키지 않으면서 가능한 한 동기화를 최소 규모로 유지해야함&lt;/li&gt;
      &lt;li&gt;애플리케이션이 오랜 시간에 걸쳐 많은 인스턴스를 생성하거나, 공유 객체에 값을 쓰는 일이 적거나, 새 인스턴스를 생성하면서 컴퓨팅 자원을 많이 소모할 때 특히 유용&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;비싱글톤 고려
    &lt;ul&gt;
      &lt;li&gt;쓰기 가능한 상태를 갖는 객체
        &lt;ul&gt;
          &lt;li&gt;빈이 쓰기 가능한 상태를 많이 가지고 있다면, 의존 객체의 각 요청을 처리하는 데 새로운 인스턴스를 생성하는 비용보다 동기화하는 비용이 더 많이 들 때&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;private 상태를 갖는 오브젝트
        &lt;ul&gt;
          &lt;li&gt;일부 의존 객체는 private 상태를 가진 빈을 사용해 빈에 의존하는 다른 객체와는 별도로 자신만의 처리 작업을 할 수 있음&lt;/li&gt;
          &lt;li&gt;이런 경우 싱글톤은 명백하게 적합하지 않음&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;cf.) &lt;strong&gt;자바 싱글톤&lt;/strong&gt; Vs &lt;strong&gt;스프링 싱글톤 패턴&lt;/strong&gt;의 차이점
    &lt;ul&gt;
      &lt;li&gt;자바 싱글톤은 &lt;strong&gt;클래스로더&lt;/strong&gt;에 의해 구현되고, 스프링의 싱글톤은 &lt;strong&gt;스프링 컨테이너&lt;/strong&gt;에 의해 구현된다.&lt;/li&gt;
      &lt;li&gt;자바 싱글톤의 scope는 코드 전체이고, 스프링 싱글톤의 scope는 해당 컨테이너 내부이다.&lt;/li&gt;
      &lt;li&gt;스프링에 의해 구현되는 싱글톤패턴은 Thread safety를 자동으로 보장한다. 자바로 구현하는 싱글톤패턴은 개발자의 로직에 따라 thread safety를 보장할수도, 보장하지 않을수도 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.5.6.2 &lt;strong&gt;빈 스코프 구현&lt;/strong&gt;하기(스프링4 버전에서 지원하는 빈 스코프)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;싱글톤(Singleton)&lt;/strong&gt; : 기본 싱글톤 스코프. 스프링 IoC 컨테이너당 하나의 객체만 생성됨&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;프로토타입(Prototype)&lt;/strong&gt; : 애플리케이션에서 요청할 때마다 스프링이 새 인스턴스를 생성&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;요청(Request)
    &lt;ul&gt;
      &lt;li&gt;웹 애플리케이션에서 사용&lt;/li&gt;
      &lt;li&gt;웹 애플리케이션에서 스프링 MVC를 사용할 때 요청 스코프를 가진 빈의 인스턴스는 모든 HTTP 요청이 있을 때마다 생성되고 요청 처리가 완료되면 소멸됨&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;세션(Session)
    &lt;ul&gt;
      &lt;li&gt;웹 애플리케이션에서 사용&lt;/li&gt;
      &lt;li&gt;웹 애플리케이션에서 스프링 MVC를 사용할 때 세션 스코프를 가진 빈의 인스턴스는 모든 HTTP 세션이 시작되면 생성되고 세션이 끝나면 소멸됨&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;글로벌 세션(Global Session)
    &lt;ul&gt;
      &lt;li&gt;포틀릿 기반 웹 애플리케이션에서 사용&lt;/li&gt;
      &lt;li&gt;글로벌 세션 스코프빈은 동일한 스프링 MVC 기반 포털 애플리케이션 내의 모든 포틀릿간에 공유될 수 있음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;스레드(Thread)
    &lt;ul&gt;
      &lt;li&gt;새로운 스레드에 의해 요청될 때 스프링에 의해 새 빈 인스턴스가 생성되고, 동일한 스레드에 대해서는 같은 빈 인스턴스 반환&lt;/li&gt;
      &lt;li&gt;이 스코프는 기본적으로 등록되지 않음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;사용자 정의(Custom)
    &lt;ul&gt;
      &lt;li&gt;org.springframework.beans.factory.config.Scope 인터페이스를 구현하고 스프링 구성에 사용자 정의 스코프를 등록해 생성할 수 있는 사용자 정의 빈 스코프&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.5.7 &lt;strong&gt;의존성 해석&lt;/strong&gt;하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;사용자 구성 파일이나 구성 클래스에 적용된 애너테이션을 보고 의존성을 해석할 수 있음&lt;/li&gt;
  &lt;li&gt;스프링은 이런 방법으로 각각의 빈들이 올바른 순서로 구성될 수 있도록 해서 각각의 빈들의 의존성이 정확하게 주입되게 함&lt;/li&gt;
  &lt;li&gt;스프링은 구성을 통해서 명시하지 않으면 사용자 빈 사이에 어떤 의존성도 인식하지 못함&lt;/li&gt;
&lt;/ul&gt;

&lt;bean id=&quot;johnMayer&quot; class=&quot;com.apress.prospring5.ch3.annotated.Singer&quot; depends-on=&quot;gopher&quot; /&gt;

&lt;bean id=&quot;gopher&quot; class=&quot;com.apress.prospring5.ch3.annotated.Guitar&quot; /&gt;

&lt;ul&gt;
  &lt;li&gt;위의 구성을 통해 johnMayer 빈이 gopher 빈에 의존한다는 것을 스프링에 알림&lt;/li&gt;
  &lt;li&gt;스프링은 빈 인스턴스를 생성할 때 이를 고려해야하며, johnMayer보다 gopher를 먼저 생성해야함&lt;/li&gt;
  &lt;li&gt;하지만 이렇게 하려면 johnMayer가 ApplicationContext에 접근해야함&lt;/li&gt;
  &lt;li&gt;따라서 스프링에게 이 참조를 주입하도록 지시해서 johnMayer.sing()매소드가 호출될 때 gopher 빈을 얻어야함&lt;/li&gt;
  &lt;li&gt;이는 Singer 빈이 ApplicationContextAware 인터페이스를 구현한다면 가능함&lt;/li&gt;
  &lt;li&gt;ApplicationContextAware를 구현하기 위해서는 이 인터페이스를 가져오는 수정자를 구현해야함&lt;/li&gt;
  &lt;li&gt;ApplicationContextAware를 구현한 빈은 스프링 IoC 컨테이너에 의해 자동으로 감지되고 해당 빈 내부에 생성된 ApplicationContext가 주입됨&lt;/li&gt;
  &lt;li&gt;이러한 과정은 빈 생성자가 호풀된 이후에 수행되므로 생성자에서 ApplicationContext를 사용하면 NullPointException이 발생&lt;/li&gt;
  &lt;li&gt;XML 구성 대신에 에너테이션을 이용해서 동일하게 구성할 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;beans&gt;
    &lt;context:component-scan base-package=&quot;com.apress.prospring5.ch3.annotated&quot; /&gt;
&lt;/beans&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;johnMayer&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@DependsOn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;gopher&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Singer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApplicationContextAware&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;nc&quot;&gt;ApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setApplicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ApplicationContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BeansException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;applicationContext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Guitar&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;guitar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Singer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(){}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;guitar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applicationContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;gopher&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Guitar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;guitar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;@DependsOn 애너테이션은 XML 구성에서 depends-on 애트리뷰트와 같음&lt;/li&gt;
  &lt;li&gt;애플리케이션을 개발할 때 이 기능을 사용할 수 있게 설계하면 안됨&lt;/li&gt;
  &lt;li&gt;대신 수정자 주입이나 생성자 주입을 이용해 의존성을 주입할 수 있게 정의해야함&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.6 &lt;strong&gt;빈에 자동 와이어링&lt;/strong&gt;하기&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;byName
    &lt;ul&gt;
      &lt;li&gt;이름에 의한 자동와이어링을 이용하면 스프링은 각 프로퍼티와 이름이 같은 빈을 찾아서 연결 시도&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;byType
    &lt;ul&gt;
      &lt;li&gt;타입에 의한 자동와이어링을 이용하면 스프링은 자동으로 ApplicationContext에서 동일한 타입의 빈을 대상 빈의 각 프로퍼티에 연결하려고 시도함&lt;/li&gt;
      &lt;li&gt;빈 타입들이 서로 연관될 때 일이 복잡해짐&lt;/li&gt;
      &lt;li&gt;같은 인터페이스를 구현한 클래스가 여러개이고 자동와이어링을 원하는 프로퍼티가 타입으로 인터페이스를 지정할 때 예외o&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Constructor(생성자)
    &lt;ul&gt;
      &lt;li&gt;주입이 수정자가 아닌 생성자를 이용해 이루어진다는 점을 제외하면 타입에 의한 와이어링과 같음&lt;/li&gt;
      &lt;li&gt;스프링은 생성자에서 가능한 많은 개수의 인수들을 일치시키려고 노력함&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;default
    &lt;ul&gt;
      &lt;li&gt;스프링은 Constructor방식과 byType방식을 자동으로 선택함&lt;/li&gt;
      &lt;li&gt;빈에 기본 생성자(인자가 없음)가 있다면 스프링은 byType방식을 이용하고 그렇지 않으면 Constructor방식을 이용&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;no
    &lt;ul&gt;
      &lt;li&gt;이것이 기본 값임&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;bean id=&quot;target&quot; autowire=&quot;byName&quot; class=&quot;com.apress.prospring5.ch3.xml.Target&quot; lazy-init=&quot;true&quot; /&gt;

&lt;ul&gt;
  &lt;li&gt;lazy-init=”true” : 최초시작 시점이 아닌 처음 요청되었을 때만 빈 인스턴스를 생성&lt;/li&gt;
  &lt;li&gt;스프링이 자동와이어링을 해야 할 빈을 알지 못하면 명시적메시지와 함께 UnsatisfiedDependencyException을 발생&lt;/li&gt;
  &lt;li&gt;해당 예외는 빈을 발견했지만, 어떤 빈을 어디에 써야 할 지 모를 때 발생&lt;/li&gt;
  &lt;li&gt;해결 방법 1 : 빈 정의에서 primary 애트리뷰트 값을 true로 설정해 스프링이 자동와이어링을 할 때 해당 빈을 먼저 사용&lt;/li&gt;
&lt;/ul&gt;

&lt;bean id=&quot;target&quot; class=&quot;com.apress.prospring5.ch3.xml.Target&quot; primary=&quot;true&quot; /&gt;

&lt;ul&gt;
  &lt;li&gt;그러나 primary 애트리뷰트 이용방식은 오직 두 개의 빈 타입만 존 재하는 경우에 사용 가능&lt;/li&gt;
  &lt;li&gt;애너테이션일 경우 두 개 이상 빈이 존재한다면 @Qualifier(“빈이름”) 애너테이션을 사용하는 것이 좋음&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;해결 방법 2 : 빈 이름을 지정하고 XML로 주입할 위치를 구성하는 방법&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;@Lazy 애너테이션&lt;/strong&gt; 사용&lt;/li&gt;
  &lt;li&gt;@Lazy는 처음 접근이 일어날 때 인스턴스가 생성될 빈을 정의하려고 클래스에 적용하는 애너테이션&lt;/li&gt;
  &lt;li&gt;스테레오 타입 애너테이션을 사용하면 하나의 빈에 하나의 구성만 만들 수 있어 각 타입의 빈이 하나씩만 있어서 빈의 이름이 중요하지 않음&lt;/li&gt;
  &lt;li&gt;때문에 애너테이션을 이용해 구성할 때 기본 자동와이어링 방식은 byType임&lt;/li&gt;
  &lt;li&gt;빈 타입이 여러 개 있을 경우 이름을 기반으로 자동와이어링하게 지정할 수 있다는 것은 매우 유용함&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Component&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;gigi&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@Lazy&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TrickyTarget&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fooOne&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fooTwo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TrickyTarget&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Target.constructor()&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.6.1 &lt;strong&gt;자동 와이어링을 사용&lt;/strong&gt;하는 경우&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;자동와이어링은 소규모 애플리케이션에서 시간을 절약할 수 있지만 많은 나쁜 사례로 이어질 수 있음&lt;/li&gt;
  &lt;li&gt;대규모 애플리케이션에서는 유연성이 떨어짐&lt;/li&gt;
  &lt;li&gt;byName을 사용하는 것이 좋은 것처럼 보일 수 있지만, 이 방법은 사용자가 자동와이어링 기능의 장점을 얻으려고 클래스에 인위적인 프로퍼티 이름을 지정하는 결과로 이어짐&lt;/li&gt;
  &lt;li&gt;중요한 애플리케이션이라면 자동와이어링을 사용하지 말아야함&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;3.7 &lt;strong&gt;빈 상속 설정&lt;/strong&gt;하기&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;때로는 같은 타입의 빈이나 공유 인터페이스를 구현하는 빈을 여러 개 정의할 필요가 있음&lt;/li&gt;
  &lt;li&gt;스프링은 ApplicationContext 인스턴스에 존재하는 다른 빈의 프로퍼티 설정을 상속받을 수 있도록 &lt;bean&gt;정의를 제공함&lt;/bean&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;bean id=&quot;parent&quot; class=&quot;com.apress.prospring5.ch3.xml.Singer&quot; p:name=&quot;John Mayer&quot; p:age=&quot;39&quot; /&gt;

&lt;bean id=&quot;child&quot; class=&quot;com.apress.prospring5.ch3.xml.Singer&quot; parent=&quot;parent&quot; p:age=&quot;0&quot; /&gt;

&lt;ul&gt;
  &lt;li&gt;이 코드에서 child 빈을 위한 &lt;bean&gt;태그에서 parent라는 별도의 애트리뷰트를 볼 수 있는데, 이는 스프링이 parent 빈을 child 빈의 부모로 간주해 구성을 상속해야 함을 나타냄&lt;/bean&gt;&lt;/li&gt;
  &lt;li&gt;ApplicationContext에서 부모 빈 정의를 룩업할 수 없게 하려면 parent 빈을 선언할 때 &lt;bean&gt;태그에 abstract=&quot;true&quot; 애트이뷰트를 추가할 수 있음&lt;/bean&gt;&lt;/li&gt;
  &lt;li&gt;자식 빈은 부모 빈에서 생성자 인수와 프로퍼티 값을 모두 상속하므로 빈 상속과 함께 두 가지 주입 방식을 모두 사용할 수 있음&lt;/li&gt;
  &lt;li&gt;공유 프로퍼티 값을 사용해 동일한 값의 빈을 여러 개 선언해야 할 때, 복사와 붙여넣기로 값을 공유하는 방식은 사용하지 말아야함&lt;/li&gt;
  &lt;li&gt;대신 구성에서 상속 계층 구조로 설정해야함&lt;/li&gt;
  &lt;li&gt;빈 구성을 상속할 때에는 자바 상속 계층 구조와 일치시킬 필요가 없다는 사실을 기억해야 함&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><summary type="html">chpater3. 스프링 IoC와 DI</summary></entry><entry><title type="html">Aws_rds_connect_time_out</title><link href="https://boniato.github.io/AWS_RDS_CONNECT_TIME_OUT/" rel="alternate" type="text/html" title="Aws_rds_connect_time_out" /><published>2020-05-06T00:00:00+00:00</published><updated>2020-05-06T00:00:00+00:00</updated><id>https://boniato.github.io/AWS_RDS_CONNECT_TIME_OUT</id><content type="html" xml:base="https://boniato.github.io/AWS_RDS_CONNECT_TIME_OUT/">&lt;h3 id=&quot;javasqlsqlnontransientconnectionexception-could-not-connect-to-addresshostspringboot2-webservicectwad1edhzetap-northeast-2rdsamazonawscomport3306typemaster--connect-timed-out&quot;&gt;“java.sql.SQLNonTransientConnectionException: Could not connect to address=(host=springboot2-webservice.ctwad1edhzet.ap-northeast-2.rds.amazonaws.com)(port=3306)(type=master) : connect timed out”&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/error/2020.05.06-aws_rds_connect_fail_application.png&quot; width=&quot;100%&quot; height=&quot;100%&quot; alt=&quot;error&quot; /&gt;&lt;/p&gt;

&lt;p&gt;EC2 서버에 접속하여 애플리케이션을 배포하려니 위와 같은 에러가 났다.&lt;/p&gt;

&lt;p&gt;결론부터 말하자면 보안그룹(Security Groups)에 Inbound rules에 EC2 서버 IP를 추가하지 않아서 났던 것이였다.&lt;/p&gt;

&lt;h3 id=&quot;1-ec2-서버에서-rds-db-인스턴스에-연결되었는지-확인하기&quot;&gt;1. EC2 서버에서 RDS DB 인스턴스에 연결되었는지 확인하기&lt;/h3&gt;

&lt;p&gt;먼저 EC2 서버에서 RDS DB 인스턴스에 연결되었는지 다음 명령어중 하나를 실행하여 확인해보자.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;telnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RDS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;nc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RDS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;port&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;간단히 nc 명령어를 통해 RDS DB 인스턴스에 연결이 실패된 것을 다음과 같이 확인 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/error/2020.05.06-aws_rds_connect_fail.png&quot; width=&quot;100%&quot; height=&quot;100%&quot; alt=&quot;error&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;2-보안그룹security-groups에-inbound-rules에-ec2-서버-ip-추가하기&quot;&gt;2. 보안그룹(Security Groups)에 Inbound rules에 EC2 서버 IP 추가하기&lt;/h3&gt;

&lt;p&gt;EC2 서버에서 &lt;strong&gt;ip addr show&lt;/strong&gt;나 &lt;strong&gt;ifconfig&lt;/strong&gt; 명령어로 IP 주소를 확인해보자.&lt;br /&gt;
eth0에서 inet IP주소를 보면 된다.&lt;/p&gt;

&lt;p&gt;AWS에서 보안그룹의 Inbound rules에서 EC2 서버 IP로 연결할 수 있는 rule을 추가한다. 위치는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AWS - RDS - Databases - DB identifier - VPC security groups - Security Groups - Inbound rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Type은 MYSQL/Aurora, Source는 Custom으로 두고 EC2 서버 IP를 입력한 후 저장한다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;다시 nc 명령어를 이용하여 RDS DB 인스턴스가 연결되는지 확인한다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/error/2020.05.06-aws_rds_connect_success.png&quot; width=&quot;100%&quot; height=&quot;100%&quot; alt=&quot;error&quot; /&gt;&lt;/p&gt;

&lt;p&gt;연결이 성공하였다면 succeeded! 메시지를 볼 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;아래는 Amazon RDS DB 인스턴스에 연결할 때 발생하는 문제를 해결하는 방법을 가이드한 링크이다.&lt;/p&gt;

&lt;p&gt;https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html&lt;/p&gt;</content><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><summary type="html">“java.sql.SQLNonTransientConnectionException: Could not connect to address=(host=springboot2-webservice.ctwad1edhzet.ap-northeast-2.rds.amazonaws.com)(port=3306)(type=master) : connect timed out”</summary></entry><entry><title type="html">Could_not_autowire._no_beans_of_foo_type_found</title><link href="https://boniato.github.io/Could_not_autowire._No_beans_of_Foo_type_found/" rel="alternate" type="text/html" title="Could_not_autowire._no_beans_of_foo_type_found" /><published>2020-03-29T00:00:00+00:00</published><updated>2020-03-29T00:00:00+00:00</updated><id>https://boniato.github.io/Could_not_autowire._No_beans_of_Foo_type_found</id><content type="html" xml:base="https://boniato.github.io/Could_not_autowire._No_beans_of_Foo_type_found/">&lt;h3 id=&quot;could-not-autowire-no-beans-of-postsrepository-type-found&quot;&gt;“Could not autowire. No beans of ‘postsRepository’ type found.”&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/posts/error/2020-03-29-Could_not_autowire_01.png&quot; width=&quot;100%&quot; height=&quot;100%&quot; alt=&quot;error&quot; /&gt;&lt;/p&gt;

&lt;p&gt;유닛 테스트 코드를 작성하니 해당 bean을 찾을 수 없어 Could not autowire 에러나 났다.
왜 유닛 테스트 코드에서만 찾지 못할까 고민하며 구글링하니 아래와 같은 해결책을 찾을 수 있었다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;올바른 패키지를 가져 왔는지 확인하기&lt;/li&gt;
  &lt;li&gt;autowire할 대상이 interface(MyService)가 아닌 구체적인 class(MyServiceImpl)로 하기.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;나 같은 경우에는 패키지가 잘못되어 이를 정정해줌으로써 해결할 수 있었다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/error/2020-03-29-Could_not_autowire_02.png&quot; width=&quot;100%&quot; height=&quot;100%&quot; alt=&quot;error&quot; /&gt;&lt;/p&gt;

&lt;p&gt;참조) https://stackoverflow.com/questions/21878714/how-to-write-junit-test-with-spring-autowire&lt;/p&gt;</content><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><summary type="html">“Could not autowire. No beans of ‘postsRepository’ type found.”</summary></entry><entry><title type="html">Query_syntax_exception: foo is not mapped</title><link href="https://boniato.github.io/Query_Syntax_Exception-Foo-is-not-mapped/" rel="alternate" type="text/html" title="Query_syntax_exception: foo is not mapped" /><published>2020-03-29T00:00:00+00:00</published><updated>2020-03-29T00:00:00+00:00</updated><id>https://boniato.github.io/Query_Syntax_Exception:%20Foo%20is%20not%20mapped</id><content type="html" xml:base="https://boniato.github.io/Query_Syntax_Exception-Foo-is-not-mapped/">&lt;h3 id=&quot;querysyntaxexception-posts-is-not-mapped&quot;&gt;“QuerySyntaxException: posts is not mapped…”&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/posts/error/2020-03-29-Query_Syntax_Exception.png&quot; width=&quot;100%&quot; height=&quot;100%&quot; alt=&quot;error&quot; /&gt;
&lt;img src=&quot;/assets/images/posts/error/2020-03-29-Query_Syntax_Exception_detail.png&quot; width=&quot;90%&quot; height=&quot;90%&quot; alt=&quot;error&quot; /&gt;
&lt;br /&gt;&lt;br /&gt;
테스트 코드를 돌리니 위와 같은 에러가 났다.
&lt;br /&gt;&lt;br /&gt;
구글링을 하니 JPQL은 대부분 대소문자 구분이 없지만, 이를 구분하는 경우 중 하나는 자바 객체명이라고 한다. 즉, &lt;strong&gt;테이블과 매핑된 도메인의 클래스명과 같아야한다&lt;/strong&gt;.
&lt;br /&gt;&lt;br /&gt;
“JPQL mostly is case-insensitive. One of the things that is case-sensitive is Java entity names. Change your query to…”
&lt;br /&gt;&lt;br /&gt;
그래서 posts의 소문자 p를 대문자로 바꾼 &lt;strong&gt;Posts&lt;/strong&gt; 로 변경하니 해결되었다.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Query&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SELECT p FROM Posts p ORDER BY p.id DESC&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;br /&gt;
참조) https://stackoverflow.com/questions/8230309/jpa-mapping-querysyntaxexception-foobar-is-not-mapped
&lt;br /&gt;&lt;/p&gt;</content><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><summary type="html">“QuerySyntaxException: posts is not mapped…” 테스트 코드를 돌리니 위와 같은 에러가 났다. 구글링을 하니 JPQL은 대부분 대소문자 구분이 없지만, 이를 구분하는 경우 중 하나는 자바 객체명이라고 한다. 즉, 테이블과 매핑된 도메인의 클래스명과 같아야한다. “JPQL mostly is case-insensitive. One of the things that is case-sensitive is Java entity names. Change your query to…” 그래서 posts의 소문자 p를 대문자로 바꾼 Posts 로 변경하니 해결되었다.</summary></entry><entry><title type="html">Study Kotlin In Action Chapter5</title><link href="https://boniato.github.io/study-kotlin-in-action-chapter5/" rel="alternate" type="text/html" title="Study Kotlin In Action Chapter5" /><published>2020-01-23T00:00:00+00:00</published><updated>2020-01-23T00:00:00+00:00</updated><id>https://boniato.github.io/study-kotlin-in-action-chapter5</id><content type="html" xml:base="https://boniato.github.io/study-kotlin-in-action-chapter5/">&lt;h5 id=&quot;kotlin-in-action-chapter5&quot;&gt;Kotlin In Action Chapter5&lt;/h5&gt;
&lt;h1 id=&quot;람다로-프로그래밍&quot;&gt;람다로 프로그래밍&lt;/h1&gt;

&lt;h2 id=&quot;1-람다-식&quot;&gt;1. 람다 식&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;람다 식(lambda expression)&lt;/strong&gt; 또는 &lt;strong&gt;람다&lt;/strong&gt;는 기본적으로 다른 함수에 넘길 수 있는 작은 코드 조각을 뜻한다.&lt;/li&gt;
  &lt;li&gt;람다는 값처럼 여기저기 전달할 수 있는 동작의 모음이다.
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;11-람다-소개-코드-블록을-함수-인자로-넘기기&quot;&gt;1.1 람다 소개: 코드 블록을 함수 인자로 넘기기&lt;/h3&gt;
&lt;p&gt;람다 식을 사용하면 함수를 선언할 필요가 없고 코드 블록을 직접 함수의 인자로 전달할 수 있다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;ㆍ익명 클래스로 리스너 구현하기&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* 자바 */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setOnClickListener&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onClickListener&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;cm&quot;&gt;/* 클릭 시 수행할 동작 */&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;ㆍ&lt;strong&gt;람다&lt;/strong&gt;로 리스너 구현하기&lt;/p&gt;
&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setOnClickListener&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* 클릭 시 수행할 동작 */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;12-람다와-컬렉션&quot;&gt;1.2 람다와 컬렉션&lt;/h3&gt;
&lt;p&gt;코틀린에서는 컬렉션 라이브러리 함수를 제공하기 때문에 필요한 컬렉션 기능을 직접 작성해야되는 불편함을 덜어준다.&lt;/p&gt;

&lt;p&gt;ㆍ람다를 사용해 컬렉션 검색하기&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;people&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;listOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Alice&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Bob&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;maxBy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* 나이 프로퍼티를 비교해서 값이 가장 큰 원소 찾기 */&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Person(name=Bob, age=31)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;ㆍ위 코드를 &lt;strong&gt;멤버 참조&lt;/strong&gt;를 사용해 컬렉션을 검색할 수 있다.&lt;/p&gt;
&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;maxBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;13-람다-식의-문법&quot;&gt;1.3 람다 식의 문법&lt;/h3&gt;
&lt;p&gt;이미 말했지만 람다는 값처럼 여기저기 전달할 수 있는 동작의 모음이다. 함수에 인자로 넘기면서 람다를 정의하는 경우가 대부분이다.
&lt;br /&gt;
ㆍ람다 식을 선언하기 위한 문법&lt;/p&gt;
&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;--------------&lt;/span&gt;      &lt;span class=&quot;p&quot;&gt;-----&lt;/span&gt;
      &lt;span class=&quot;err&quot;&gt;파라미터&lt;/span&gt;          &lt;span class=&quot;err&quot;&gt;본문&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;람다는 항상 중괄호 사이에 위치한다.&lt;/li&gt;
  &lt;li&gt;인자 목록 주변에 괄호가 없다.&lt;/li&gt;
  &lt;li&gt;화살표(-&amp;gt;)가 인자 목록과 람다 본문을 구분해준다.&lt;/li&gt;
  &lt;li&gt;람다 식을 변수에 저장할 수 있다.&lt;/li&gt;
  &lt;li&gt;람다가 저장된 변수를 다른 일반 함수와 마찬가지로 다룰 수 있다.
    &lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// result : 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><summary type="html">Kotlin In Action Chapter5 람다로 프로그래밍</summary></entry><entry><title type="html">Study Kotlin In Action Chapter4</title><link href="https://boniato.github.io/study-kotlin-in-action-chapter4/" rel="alternate" type="text/html" title="Study Kotlin In Action Chapter4" /><published>2020-01-14T00:00:00+00:00</published><updated>2020-01-14T00:00:00+00:00</updated><id>https://boniato.github.io/study-kotlin-in-action-chapter4</id><content type="html" xml:base="https://boniato.github.io/study-kotlin-in-action-chapter4/">&lt;h5 id=&quot;kotlin-in-action-chapter4&quot;&gt;Kotlin In Action Chapter4&lt;/h5&gt;
&lt;h1 id=&quot;클래스-객체-인터페이스&quot;&gt;클래스, 객체, 인터페이스&lt;/h1&gt;

&lt;h2 id=&quot;1-클래스와-인터페이스&quot;&gt;1. 클래스와 인터페이스&lt;/h2&gt;

&lt;h3 id=&quot;11-클래스&quot;&gt;1.1 클래스&lt;/h3&gt;

&lt;p&gt;코틀린에서 클래서는는 기본적으로 &lt;strong&gt;final&lt;/strong&gt;이며 &lt;strong&gt;public&lt;/strong&gt;이다.&lt;br /&gt;
조슈아 블로그(Joshua Block)가 쓴 ‘Effective Java’에서 “&lt;em&gt;상속을 위한 설계와 문서를 갖추거나, 그럴 수 없다면 상속을 금지하라&lt;/em&gt; “라는 철학을 따른다. 이는 특별히 하위 클래스에서 오버라이드하게 의도된 클래스와 메소드가 아니라면 모두 final로 만들라는 뜻이다. 클래스를 상속하는 방법에 대해 정확한 규칙을 제공하지 않는다면, 상속을 받는 클래스에서 기존 의도와 다른 방식으로 메소드를 오바라이드할 위험이 있기 때문이다.&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;12-인터페이스&quot;&gt;1.2 인터페이스&lt;/h3&gt;
&lt;p&gt;코틀린 인터페이스는 클래스 이름 뒤에 콜론(&lt;strong&gt;:&lt;/strong&gt;)을 붙이고 인터페이스와 클래스 이름을 적는 것으로 클래스 확장과 인터페이스를 구현한다.&lt;br /&gt;
코틀린 인터페이스 안에는 추상 메소드뿐 아니라 구현이 있는 메소드도 정의 할 수 있다. 다만 인터페이스에는 아무런 상태(필드)도 들어갈 수 없다.
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;ㆍ추상 메소드가 있는 인터페이스 선언&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Clickable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;ㆍClickable 인터페이스의 click 추상메소드를 구현하는 클래스&lt;/p&gt;
&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Clickable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I was clicked&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;ㆍ위의 코드 실행&lt;/p&gt;
&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//I was clicked&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;ㆍ상속한 다중 인터페이스 메소드 구현&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Clickable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showOff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I'm clickable!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
&lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Focusable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setFocus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I ${if (b) &quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;got&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; else &quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lost&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;} focus.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showOff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I'm focusable!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Clickable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Focusable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;I was clicked&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;showOff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Clickable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showOff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Focusable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showOff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// I was clicked&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setFocus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// I got focus.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showOff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// I'm clickable!  I'm focusable!&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;2-생성자와-프로퍼티&quot;&gt;2. 생성자와 프로퍼티&lt;/h2&gt;
&lt;p&gt;코틀린은 주 생성자(primary constructor)와 부 생성자(secondary constructor)를 구분한다.
주 생성자는 클래스를 초기화할 때 주로 사용하는 간략한 생성자로 클래스 본문 밖에서 정의한다.
부 생성자는 클래스 본문 안에서 정의한다.
또한 초기화 블록(initializer block)을 통해 초기화 로직을 추가할 수 있다.&lt;/p&gt;

&lt;h3 id=&quot;21-주-생성자와-초기화-블록&quot;&gt;2.1 주 생성자와 초기화 블록&lt;/h3&gt;

&lt;p&gt;다음은 간단한 클래스를 선언하는 예제이다.&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;nickname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 예제에서 클래스 이름 뒤의 괄호로 둘러싸인 코드를 주 생성자(primary constructor)라고 부른다. 
주 생성자는 &lt;strong&gt;생성자 파라미터를 지정하고 그 생성자 파라미터에 의해 초기화되는 프로퍼티를 정의하는 두 가지 목적&lt;/strong&gt;에 쓰인다.
위 코드를 명시적인 선언으로 풀어쓰면 다음과 같다.&lt;/p&gt;
&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_nickname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;cm&quot;&gt;/* 파라미터가 하나만 있는 주 생성자 */&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;nickname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;cm&quot;&gt;/* 초기화 블록 */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;nickname&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_nickname&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;constructor&lt;/strong&gt; 키워드는 주 생성자나 부 생성자 정의를 시작할 때 사용한다.&lt;br /&gt;
&lt;strong&gt;init&lt;/strong&gt; 키워드는 초기화 블록을 시작한다. 초기화 블록은 클래스의 객체가 만들어질 때(인스턴스화될 때) 실행될 초기화 코드가 들어간다. 초기화 블록은 주 생성자와 함께 사용한다.&lt;/p&gt;

&lt;h2 id=&quot;3-데이터-클래스&quot;&gt;3. 데이터 클래스&lt;/h2&gt;

&lt;h2 id=&quot;4-클래스-위임&quot;&gt;4. 클래스 위임&lt;/h2&gt;

&lt;h2 id=&quot;5-object-키워드-사용&quot;&gt;5. object 키워드 사용&lt;/h2&gt;</content><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><summary type="html">Kotlin In Action Chapter4 클래스, 객체, 인터페이스</summary></entry><entry><title type="html">Make Blog To Be Searched On Google</title><link href="https://boniato.github.io/make-blog-to-be-searched-on-google/" rel="alternate" type="text/html" title="Make Blog To Be Searched On Google" /><published>2020-01-13T00:00:00+00:00</published><updated>2020-01-13T00:00:00+00:00</updated><id>https://boniato.github.io/make-blog-to-be-searched-on-google</id><content type="html" xml:base="https://boniato.github.io/make-blog-to-be-searched-on-google/">&lt;h1 id=&quot;github-구글-검색-가능하도록-만드는-방법&quot;&gt;Github 구글 검색 가능하도록 만드는 방법&lt;/h1&gt;
&lt;h3 id=&quot;google-search-console-에서-url-등록하기&quot;&gt;Google Search Console 에서 URL 등록하기&lt;/h3&gt;

&lt;h3 id=&quot;1-google-search-console-접속&quot;&gt;1. &lt;a href=&quot;https://search.google.com/search-console/about&quot;&gt;Google Search Console&lt;/a&gt; 접속&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/post1/post1_GoogleSearch01.png&quot; alt=&quot;Alt text&quot; /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;2-도메인-혹은-url-등록&quot;&gt;2. 도메인 혹은 URL 등록&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/post1/post1_GoogleSearch02.png&quot; width=&quot;90%&quot; height=&quot;90%&quot; title=&quot;등록&quot; alt=&quot;등록&quot; /&gt;&lt;/p&gt;

&lt;p&gt;본인의 Github URL을 입력합니다.
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;3-html-파일-다운로드&quot;&gt;3. HTML 파일 다운로드&lt;/h3&gt;

&lt;p&gt;생성된 html을 다운받습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/post1/post1_GoogleSearch03.png&quot; width=&quot;80%&quot; height=&quot;80%&quot; title=&quot;HTML파일다운로드&quot; alt=&quot;HTML파일다운로드&quot; /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;4-boniatoboniatogithubio-에-html-파일-업로드&quot;&gt;4. boniato/boniato.github.io 에 HTML 파일 업로드&lt;/h3&gt;

&lt;p&gt;본인 github 블로그 /폴더에 다운받은 HTML 파일을 업로드 합니다.
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;5-확인-버튼을-클릭하면-다음과-같이-소유권이-확인됨-창을-볼-수-있습니다&quot;&gt;5. 확인 버튼을 클릭하면 다음과 같이 “소유권이 확인됨” 창을 볼 수 있습니다.&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/post1/post1_GoogleSearch04.png&quot; width=&quot;80%&quot; height=&quot;80%&quot; title=&quot;소유권확인&quot; alt=&quot;소유권확인&quot; /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;cf-네이버와-다음에도-본인-url을-확인-및-등록해봅니다&quot;&gt;cf.) 네이버와 다음에도 본인 URL을 확인 및 등록해봅니다.&lt;/h3&gt;
&lt;p&gt;&lt;br /&gt;
       
&lt;a href=&quot;https://searchadvisor.naver.com/search&quot;&gt;NAVER Search Advisor&lt;/a&gt; 등록
&lt;br /&gt;
       
&lt;a href=&quot;https://register.search.daum.net/index.daum&quot;&gt;daum 검색 등록&lt;/a&gt; 등록
&lt;br /&gt;&lt;/p&gt;</content><author><name>Ahreum Lee</name><email>ahh.reum.lee@gmail.com</email><uri>https://thatisgood.tistory.com/</uri></author><summary type="html">Github 구글 검색 가능하도록 만드는 방법 Google Search Console 에서 URL 등록하기</summary></entry></feed>