<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>luca_wiiii.log</title>
        <link>https://velog.io/</link>
        <description>No Experience Backend Developer </description>
        <lastBuildDate>Sun, 09 May 2021 16:46:35 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>luca_wiiii.log</title>
            <url>https://images.velog.io/images/luca_wiiii/profile/14cc7aef-8783-4992-8c87-cc3a7eff5489/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. luca_wiiii.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/luca_wiiii" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Spring] Spring에서 의존성 주입하기]]></title>
            <link>https://velog.io/@luca_wiiii/Spring-Spring%EC%97%90%EC%84%9C-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85%ED%95%98%EA%B8%B0-qw129414</link>
            <guid>https://velog.io/@luca_wiiii/Spring-Spring%EC%97%90%EC%84%9C-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85%ED%95%98%EA%B8%B0-qw129414</guid>
            <pubDate>Sun, 09 May 2021 16:46:35 GMT</pubDate>
            <description><![CDATA[<br>

<p>저번 포스팅에서 일반적인 상황의 의존성 주입에 대해 공부했다. 이번에는 <code>Spring Framework</code>에서 사용하는 의존성 주입에 대해 집중하여 다룰 예정이다. </p>
<br>

<hr>
<p><br><br></p>
<h2 id="ioc-inversion-of-control">IoC (Inversion of Control)</h2>
<br>

<p>저번 포스팅에서 간단히 다뤘었지만, <code>Spring Framework</code>에서 의존성 주입을 공부하기 전에 다시 <code>IoC</code>에 대해 언급하려고 한다.</p>
<h3 id="ioc의-개념">IoC의 개념</h3>
<p><code>Inversion of Control(제어의 역전)</code>, IoC는 객체의 흐름, 생명주기(Life-Cycle) 등을 관리하는 것을 위임하는 방식의 프로그래밍 설계를 의미한다. <strong>결국, 개발 주체가 되는 개발자가 직접 위와 같은 것을 관리하는 것이 아닌 제 3자 **<code>Spring</code></strong>같은 경우엔** <code>Spring Container</code><strong>에게 이 권한을 위임하여 IoC를 이루게 된다.</strong> 이러한 기능을 하는 Container를 <code>IoC Container</code>라고 일컫는다.</p>
<h3 id="ioc--di">IoC == DI?</h3>
<p><code>Spring</code> 에서 이 두 개념이 같게 사용이 되고 있고 실제로 같다고 생각하는 사람도 많다. 하지만 이는 사실이 아니고, 따지고 보면 DI가 IoC의 분류 중 하나이다.  </p>
<p><img src="https://images.velog.io/images/luca_wiiii/post/c3f28076-2394-406e-aae3-b787ed9f8c55/image.png" alt=""></p>
<ul>
<li>DL(Dependency Lookup) : 저장소에 저장되어 있는 Bean에 접근하기위해 컨테이너가 제공하는 API를 이용하여 Bean을 검색(Lookup)하는 것.</li>
<li>DI(Dependency Injection) :  컨테이너가 주체가 되어 애플리케이션 코드에 의존관계를 주입해 주는 것.<ul>
<li>각 클래스간의 의존관계를 빈설정(Bean Definition)정보를 바탕으로 컨테이너가 자동으로 연결함. </li>
</ul>
</li>
</ul>
<p>DL를 사용하게 된다면 종속성이 많이 생기게 되므로 DI를 많이 사용한다. 그래서 많은 개발자들이 IoC와 DI를 겸해 Spring에서 그 의미를 사용하고 있는 것 같다. </p>
<br>
<br>

<h2 id="spring-에서-의존성-주입하기">Spring 에서 의존성 주입하기</h2>
<br>

<p><code>Spring</code>에서 의존성을 주입하는 방식은 대표적으로 3가지를 들 수 있다. </p>
<ul>
<li>Field Injection</li>
<li>Setter Injection</li>
<li>Constructor Injection </li>
</ul>
<br>

<h3 id="field-injection">Field Injection</h3>
<br>

<pre><code class="language-java">@Service
public class HelloService {


   @Autowired  // field injection
   private HelloRepository helloRepository;

   ... 
   }</code></pre>
 <br>

<p>가장 쉬운 의존성 주입 방식이다.  여기서,</p>
<p><code>@Autowired</code> 어노테이션은 말 그대로 스프링 IoC 컨테이너 안에 있는 객체인 <code>bean</code>들이 자동으로 연결(wire)이 되게 하는 <code>Spring Framework</code> 의 기능이다.   </p>
<br>

<p>이러한 Field Injection은 짧은 줄만 기입하면 되기 때문에 편리함을 주지만, Mock 을 주입하기가 어려운 구조이기 때문에 UnitTest가 어려워 *<em>사실상 DI의 장점을 살리지 못한다. *</em></p>
<p><strong>그래서 Field Injection은 지양하는 의존성 주입 방식이다.</strong></p>
<br>
<br>

<h3 id="setter-injection">Setter Injection</h3>
<br>

<pre><code class="language-java">@Service
public class HelloService {


    // setter injection
    private HelloRepository helloRepository;

    @Autowired
    public void setHelloRepository(HelloRepository helloRepository) {
        this.helloRepository = helloRepository;
    }
   ... 
   }</code></pre>
<br>
Setter를 이용해 의존성을 주입하는 방식이고, Field Injection이 가지지 못하는 다형성을 가지게 되어 Mock을 제작하여 UnitTest를 진행할 수 있는 의존성 주입방식이다.

<p>그러나 <code>Spring 3.x</code>까지만 권장된 방식이고, 그 다음 버전에서는 권장하지 않는 방식이다. 여러 이유가 있을 수 있지만 개발 중간에 어떠한 공격자가 위 코드의 <code>helloRepository</code>를 교체할 수도 있고, Setter로 인한 의도치 않은 변경이 이루어질 수도 있기 때문에 보안상 보기 좋지가 않다. 그렇기 때문에 <code>Spring 4.x</code> 버전을 사용하고 있는 *<em>지금 권장하는 방식은 아니라 할 수 있다. *</em></p>
<br>
<br>

<h3 id="constructor-injection">Constructor Injection</h3>
<br>

<pre><code class="language-java">@Service
public class HelloService {


    // Constructor injection
    private HelloRepository helloRepository;


    @Autowired // Spring 4.3 이후 없어도 spring이 알아서 injection을 해줌.
    public HelloService(HelloRepository helloRepository) {
        this.helloRepository = helloRepository;
    }

   ... 
   }</code></pre>
<br>

<p><strong>생성자를 이용한 DI는 현재 존재하는 의존성 주입 방법 중 가장 권장되어 있는 방식이다.</strong> 생성자가 존재함으로써 Field Injection이 가지는 문제점과 Setter Injection이 가지는 보안적인 문제점을 모두 해결하고 있다. </p>
<p>또한 <code>Spring 4.3</code> 이후 가장 권장되는 방법으로, <code>@Autowired</code> 어노테이션도 생략이 가능하다. 생략을 하더라도, <code>IoC 컨테이너</code>가 알아서 <code>bean</code>을 연결해준다. </p>
<p>여기서 <code>lombok</code>을 사용하면 더 간단한 코드로 정리할 수 있는데, <code>lombok</code>의 <code>AllArgsConstructor</code>나 <code>RequiredArgsConstructor</code> 가 생성자를 이용한 DI 조차 해주기 때문에 어노테이션만 클래스에 달아주면 코드가 더 간단해진다.</p>
<br>

<pre><code class="language-java">@Service
@AllArgsConstructor
public class HelloService {


    // Constructor injection
    private HelloRepository helloRepository;

  /* -&gt; 이 과정을 lombok의 AllArgsConstructor가 대체해줌.
    @Autowired // Spring 4.3 이후 없어도 spring이 알아서 injection을 해줌.
    public HelloService(HelloRepository helloRepository) {
        this.helloRepository = helloRepository;
    }
  */
   ... 
   }</code></pre>
<br>

<p>이렇게 기존 Constructor Injection 보다 훨씬 간편한 코드로 작성할 수 있다. 그러나 웬만하면 (<del><em>상황에 따라 다를 수 있지만</em></del>) <code>Repository</code> 같은 저장소는 변하지 않아야 하는 성격을 가지기 때문에 <code>final</code>로 사용하기도 한다. </p>
<p>그런 경우에는 <code>AllArgsConstructor</code> 대신, 초기화 되지않은 <code>final</code> 필드나, <code>@NonNull</code> 이 붙은 필드에 대해 생성자를 생성해 주는 <code>RequiredArgsConstructor</code>를 사용하는 것이 더 권장된다. </p>
<br>

<pre><code class="language-java">@Service
@RequiredArgsConstructor
public class HelloService {


    // Constructor injection
    private final HelloRepository helloRepository;

   ... 
   }</code></pre>
<br>

<p><code>RequiredArgsConstructor</code>를 사용한 Constructor Injection은 이러한 모습으로 코드를 단순화할 수 있다. </p>
<br>
<br>

<h3 id="맺음">맺음</h3>
<p>향후 <code>@Autowired</code> 어노테이션에 대해 자세히 다뤄볼 포스팅을 할 기회가 오면 좋겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spring] 의존성 주입(Dependency Injection)]]></title>
            <link>https://velog.io/@luca_wiiii/Spring-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85Dependency-Injection</link>
            <guid>https://velog.io/@luca_wiiii/Spring-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85Dependency-Injection</guid>
            <pubDate>Sun, 09 May 2021 15:05:09 GMT</pubDate>
            <description><![CDATA[<h2 id=""></h2>
<br>
MVC 구조와 같은 객체 지향 프로그래밍을 하다 보면, 의존성 주입(Dependency Injection, 이하 DI)을 하게 된다. 그렇기 때문에 객체 지향 설계를 주로 다루는 Java Spring에게 있어서 DI는 가장 기본적이고, 꼭 알아야 하는 개념이다.

<hr>
<br>

<h2 id="의존성-주입이란">의존성 주입이란?</h2>
<br>
말 그대로 객체에 다른 객체의 의존성을 주입하는 것이다. 하지만 이렇게 설명하면 헷갈리고 이해가 매우 어렵다. (붕어같은 내 머리로는 이런 식으로 기억했다간 내일이면 까먹는다🤦‍♂️🤦‍♂️)  그렇기 때문에 먼저 의존성이 어떤 것인지에 대해 알아봐야 한다.
<br><br>
<br>

<h3 id="의존성-dependency">의존성 (Dependency)</h3>
<br>


<pre><code class="language-java">public class Computer {
    // Processor에 대해 의존성이 생기게 됨.
    Private Processor processor;
}</code></pre>
<br>

<p>위 코드를 보자. </p>
<p>컴퓨터인 <code>Computer</code>객체에서 <code>Processor</code>객체를 불러오게 되었다. 이 두 객체 사이에서 의존성이 발생하였다고 표현하며, <code>Computer</code>가 <code>Processor</code> 객체를 가져다 쓰게 되므로, <code>Computer</code>가 <code>Processor</code>에 대해 의존성을 가진다.</p>
<p>결국 객체지향 프로그래밍에서 객체에서 다른 객체를 사용할 때 의존성이 발생하게 되는 것이다.
<br><br></p>
<h3 id="문제점">문제점</h3>
<br>
그러나 의존성을 발생하는 단계에서 문제점이 생기곤 한다. 바로 생산성에 문제가 생기는 문제점을 갖게 되는데 밑 코드를 들여다 보면, 

<pre><code class="language-java">public class Computer {
    Private Processor processor;
    Private Gpu gpu;
    Private Memory memory;

    public Computer {
        Processor Intel = new Processor();
        Gpu Geforce = new Gpu();
        Memory memory1024 = new Memory();
         ... 
        }
   ...
   }</code></pre>
<p><code>Computer</code>를 만들기 위해 여러 객체(부품)을 가지고 와야 하는데, 해당 객체들을 직접 생성해서 의존성을 만들게 되면 향후 부품에 문제가 생기거나 업그레이드를 위해 부품을 교체해야 하는 일이 생기게 되면 문제가 생긴 부품의 클래스도 수정해야할 뿐더러, <code>Computer</code> 클래스도 다시금 수정해야 하는 번거로움이 생긴다. </p>
<p>우리가 일체형 컴퓨터보다 조립형 컴퓨터를 오래 사용하는 것도 같은 맥락이지 않을까? (문제 있는 부품을 그때그때 고쳐서 개조할 수 있으니까!!)
<br>
단편적인 예시였지만 클래스가 만들어내는 여러 의존성을 만들어내게 된다면 관리하기가 매우 어려워지게 될 것이다. 이는 코드의 가독성도 해치게 되며 무엇보다 생산성을 잃어버린다. 
<br></p>
<br>

<h3 id="해결방법--의존성-주입">해결방법 : 의존성 주입</h3>
<br>

<p>그래서 이를 해결할 수 있는 방법이 <code>의존성 주입</code>이다. 위 코드에서 처럼 직접 생성하여 의존성을 만들어내지 말고 <strong>외부에서 생성된 객체를 주입받는 것이다.</strong> </p>
<pre><code class="language-java">public class Computer {
    Private Processor processor;
    Private Gpu gpu;
    Private Memory memory;

 //   public Computer { // 강한 결합의 의존성 생성 방식 (문제점)
 //       Processor Intel = new Processor();
 //       Gpu Geforce = new Gpu();
 //       Memory memory1024 = new Memory();
 //       ... 
 //        }

 public Computer(Processor processor, Gpu gpu, Memory memory) {
      // 직접 new를 통해 객체를 생성하지 않고, 외부에서 받아서 의존성을 주입. 
         this.processor = processor;
        this.gpu = gpu;
        this.memory = memory;
     ...
    }
 ...
   }</code></pre>
<p>위 코드는 앞서 소개한 문제점을 개선한, <strong>생성자를 이용해</strong> 의존성 주입을 한 코드이다. 이렇게 객체 내부에서 <code>new</code>를 통한 직접 의존성 생성을 하지 않고, 외부에서 생성한 객체를 의존성으로 주입해주면 다형적이지 않아 생산성이 떨어지는 문제점을 해소하게 된다. 이렇게 외부에서 의존성을 넣어주게 되면 *<em>외부에서 제어가 된 것을 받아서 쓰기 때문에 IoC(Inverse of Control : 제어권의 역전)이라 DI를 부르기도 한다. *</em>
<br><br></p>
<h3 id="의존성-주입의-장점">의존성 주입의 장점</h3>
 <br>

<p> 물론 이와 같은 문제점만 해결한다고 의존성 주입을 사용하는 것은 아니다. 의존성 주입을 함으로써 여러 장점을 얻을 수가 있는데,</p>
<ul>
<li><p>코드가 다형성을 가지기 때문에 생산성이 올라간다. </p>
</li>
<li><p>코드가 단순해져 가독성이 좋고 재활용성이 생긴다. </p>
<ul>
<li>Test code를 작성하는데 용이하다.</li>
<li>Mocking을 하여 다른 Mock 객체에 넣어줄 수 있으므로 각 Unit을 Test할 수 있다. </li>
</ul>
<p>정도를 가장 큰 장점으로 들을 수 있다.</p>
</li>
</ul>
<br> 
<br>

<h2 id="spring에서의-의존성-주입">Spring에서의 의존성 주입</h2>
<br>
그러나 의존성이 많아지게 된다면, 의존성들을 관리하기가 쉽지 않은 것은 당연하다. 또한, 외부에서 객체를 생성해서 그 의존성이 필요한 객체에 의존성을 주입해주어야 하는데 그럴 때마다 외부에서 객체를 생성하는 것도 번거로운 일이 된다. 

<br>


<br>

<p>근데 그 의존성을 관리하고 외부에서 의존성을 생성해주는 일을 Spring이라는 Framework가 해준다. 바로 <code>Spring Container</code>라는 <code>Spring</code>의 핵심 컴포넌트이자 IoC 컨테이너가 이를 관리해주는데, 우리는 이 <code>Spring Container</code>를 통해 더욱이 편하게 개발할 수 있다. </p>
<h3 id="맺음">맺음</h3>
<p><code>Spring</code>에서 DI를 하는 것은 다음 포스트에서 다시 다룰 예정이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발자의 길에 들어서며  ]]></title>
            <link>https://velog.io/@luca_wiiii/%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-%EA%B8%B8%EC%97%90-%EB%93%A4%EC%96%B4%EC%84%9C%EB%A9%B0</link>
            <guid>https://velog.io/@luca_wiiii/%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-%EA%B8%B8%EC%97%90-%EB%93%A4%EC%96%B4%EC%84%9C%EB%A9%B0</guid>
            <pubDate>Tue, 04 May 2021 06:41:09 GMT</pubDate>
            <description><![CDATA[<h2 id="🌞-첫-블로그-첫-포스팅">🌞 첫 블로그, 첫 포스팅</h2>
<br>


<p>인생 살면서 아마 처음으로 블로그(혹은 벨로그)를 작성 및 운영해보는 순간이다. 이와 같은 순간을 겪을 때마다 내가 개발자가 되어가는 과정이라 생각하니, 이런 내가 어색해지기도 한다. 
<br>
앞으로 얼마나 열심히 내가 매진할 지 모르지만, 이 블로그에 나도 여타 개발자들과 같이 개발 공부를 하면서 알게 되는 좋은 정보나 느끼게 된 점, 고쳐야 할 점 등을 공유하고자 한다. 하지만 모태가 문과 놈이기 때문에 남들이 관심없는 가끔 글을 쓸 지도 모르겠다. <strong>(이 글과 같은?)</strong></p>
<hr>
<h2 id="나는-아무-것도-몰랐다🤦♂️">나는 아무 것도 몰랐다🤦‍♂️</h2>
<br>

<h4 id="4차-산업혁명과-개발자의-시대에-살고-있다"><em>&quot;4차 산업혁명과 개발자의 시대에 살고 있다.&quot;</em></h4>
<br>

<p>&#39;컴퓨터공학&#39;은 굉장히 핫한 전공이고, 타 전공생들도 IT 계열로 진로를 바꿔  넘어와 열심히 공부하고 있다는 것은 알았지만 나는 말 그대로 아무 것도 몰랐었다. 전공 3년을 마치고 나서야 내 진로를 생각할 때쯤 되어 이를 체감할 수 있었다. </p>
<br>

<p>사실 대학원에 진학할 생각을 오랫동안 해왔기 때문에, 코딩테스트 준비나 포트폴리오가 취업이나 향후 개발자의 삶에 있어서 큰 도움이 될 것임을 알고 있었지만 실제로 그렇게 살지는 못했다. 
<br></p>
<p>물론 지금 생각하면 핑계라고  여겨지지만 <code>백준</code>이나 <code>프로그래머스</code>, <code>해커랭크</code> 등 PS 사이트에서 문제를 푸는 것은 내게 익숙하지도 않고 내가 지금 당장 갈 길과 거리가 있다고 생각했다. 왜냐하면 연구실에서 해야 하는 프로젝트와 전공 수업 듣기도 빠듯했으니까. 
<br></p>
<p>어느 기회에선가 우리 과에 이른바 &#39;좀 코드 치는&#39; 선배들만 들어가 활동했다는 <code>소프트웨어 마에스트로</code>에 지원서를 냈다. 그 선배들과 나는 굉장히 괴리감이 있었으며 나는 스스로 항상 부족하고 때가 되지 않았다 생각했기에 4학년이 되고 나서야 지원을 해보게 되었다. 
<br>
<img src="https://images.velog.io/images/luca_wiiii/post/307fccec-cc4b-4044-922d-0be238105a7c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-04%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%202.49.39.png" alt=""></p>
<h4 id="결과는-위처럼-1차-코테-통과-후-찾아온-2차-코테에서-떨어졌다">결과는 위처럼 1차 코테 통과 후 찾아온 2차 코테에서 떨어졌다.</h4>
<br>
1차 코테와 크게 난이도의 차이는 있지 않았던 것으로 생각하지만 한 문제 한 문제가 턱턱 숨이 막혔던 것 같았다. 애초에 붙고자 하는 희망을 가지고 도전한 것은 아니지만, 내 현 위치를 알게 되었다고나 할까. 내게 있어서 너무나 좋은 경험이었다. 
<br><br>

<p>사실 시험에 떨어진 지는 한 두 달 반이 넘었다. 시험 보자마자 탈락을 예상했으니, 결과가 나오는 기간까지 합치면 대략 세 달은 지났다. 그럼 이 100일 가까운 소중한 시간동안 무엇을 했냐면 바로 나의 미래에 대해서 생각했다.</p>
<br>
결과적으로 말하자면 학교에서 열심히 다니던 연구실도 나오게 되었고, 백엔드 개발에 도전하고 있다. 짧은 기간이었지만 소프트웨어 마에스트로를 준비하면서 같이 준비하는 사람들과 이야기와 정보를 교류하며 스스로 많은 점을 느꼈던 것 같다. <b>다들 진짜진짜 열심히 살고 있더라.</b> 1년 반동안 연구실 학부 인턴한 경험이 아깝게 느껴지기도 하지만 한편으로는 FE, iOS, 안드로이드 혹은 AI, DevOps까지 다양하게 경험해보지 못하고 BE로 방향을 정하게 된 것 같아 아쉽기도 하다. 하여튼 지나간 것은 지나간 거고 앞으로 열심히 하면 되겠지. 

<hr>
<h3 id="맺음">맺음</h3>
<p>앞으로 자주 찾아뵙도록 (노력)하겠습니다.</p>
]]></description>
        </item>
    </channel>
</rss>