[Spring Boot] Java Code๋กœ ์ง์ ‘ Spring Bean ๋“ฑ๋ก

2021. 8. 13. 08:00ใ†Back-End ์ž‘์—…์‹ค/Spring Framework

728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”? ์ฃผ๋‹ˆํ•˜๋ž‘ ์ž…๋‹ˆ๋‹ค.

์ฃผ๋‹ˆํ•˜๋ž‘์€ Spring Boot์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

์˜ค๋Š˜์€ Java Code๋กœ ์ง์ ‘ Spring Bean ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๊ณต๋ถ€ ํ•ด ๋ณด๋„๋ก ํ•  ๊ฒƒ์ด์—์š”.

๋ฐ”๋กœ ์‹œ์ž‘ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

 

์ฝ”๋“œ์— ๊ด€๋ จํ•œ ๋‚ด์šฉ์€ ์ฃผ๋‹ˆํ•˜๋ž‘์˜ Github์—์„œ ํ™•์ธ ํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!




 

 

๐Ÿ“‹ ๋ชฉ์ฐจ


01.[Spring Boot] thymeleaf์™€ Spring Boot
02.[Spring Boot] Spring Web ๊ฐœ๋ฐœ ๊ธฐ์ดˆ
03.[Spring Boot] ํšŒ์› ๊ด€๋ฆฌ ์˜ˆ์ œ - Backend
04.[Spring Boot] Service ๊ฐœ๋ฐœ ๋ฐ Test Case ์ž‘์„ฑ
05.[Spring Boot] Spring Bean๊ณผ ์˜์กด๊ด€๊ณ„
06.[Spring Boot] Java Code๋กœ ์ง์ ‘ Spring Bean ๋“ฑ๋ก
07.[Spring Boot] ๋“ฑ๋ก, ๋ชฉ๋ก ๋ณด๊ธฐ ๊ตฌํ˜„ํ•˜๊ธฐ
08.[Spring Boot] ๊ธฐ์กด ์ฝ”๋“œ ์† ์•ˆ๋Œ€๊ณ , ์„ค์ •์œผ๋กœ ๊ตฌํ˜„ Class ๋ณ€๊ฒฝ
09.[Spring Boot] ํ†ตํ•ฉ Test
10.[Spring Boot] JPA
11.[Spring Boot] Spring Data JPA
12.[Spring Boot] AOP

 

 


 

 

๐Ÿ“Œ Java Code๋กœ ์ง์ ‘ Spring Bean ๋“ฑ๋ก


๋จผ์ € ํšŒ์› Service์™€ ํšŒ์› Repository์— @Service, @Repository, @Autowired๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ฉด ์–ด๋–ค ํ˜„์ƒ์ด ๋ฐœ์ƒํ• ๊นŒ์š”?

 

MeberService.java

package hello.hellospring.service;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemoryMemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

// ์ปดํฌ๋„ŒํŠธ ์Šค์บ” ๋ฐฉ์‹์˜ Service
//@Service
public class MemberService {   // Service ์ชฝ์€ ๋น„์ฆˆ๋‹ˆ์Šค ์šฉ์–ด์— ๋งž๊ฒŒ ์ด๋ฆ„ ๋“ฑ์„ ์ ์–ด์•ผ ํ•œ๋‹ค.
        // ์•„๋ž˜ ๋‚ด์šฉ์—์„œ repository ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , Service Test์—์„œ ๋˜ new๋ฅผ ํ†ตํ•ด Repository๋ฅผ ์ƒ์„ฑํ•ด์„œ ํ…Œ์ŠคํŠธํ•˜๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜๊ฒŒ ๋œ๋‹ค.
//  private final MemoryMemberRepository memberRepository = new MemoryMemberRepository();

    // ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด ์ค€๋‹ค.
    private final MemoryMemberRepository memberRepository;

    // @Service๊ฐ€ ์žˆ๋Š” Service๊ฐ€ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ, @Autowired๊ฐ€ ๋ถ™์€ ์ƒ์„ฑ์ž๋Š” ์Šคํ”„๋ง์ด ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋นˆ์œผ๋กœ ๊ด€๋ฆฌํ•  ๋•Œ, ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, ์ด ๋•Œ MemberService๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.
//    @Autowired
    public MemberService(MemoryMemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    } // ์ƒ์„ฑ์ž ๋

    // ํšŒ์› ๊ฐ€์ž…
    public Long join(Member member) {
        // ๊ฐ™์€ ์ด๋ฆ„์ด ์žˆ๋Š” ์ค‘๋ณต ํšŒ์› ๊ฐ€์ž… ๋ฐฉ์ง€
//        Optional<Member> result = memberRepository.findByName(member.getName());
//
//        result.ifPresent(memeber -> { // ifPresent๋Š” ํ•ด๋‹น ๊ฐ’์ด Null์ด ์•„๋‹ˆ๊ณ , ์–ด๋–ค ๊ฐ’์ด ์žˆ์œผ๋ฉด ๋™์ž‘ (Option๋กœ ๊ฐ์‹ธ๋ฉด ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
//            throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์› ์ž…๋‹ˆ๋‹ค.");
//        });

        // ์œ„์— ์ฝ”๋“œ ๋ณด๋‹ค ๋” ์ข‹์€ ์ฝ”๋“œ
//        memberRepository.findByName(member.getName()).ifPresent(member1 -> {
//            throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์› ์ž…๋‹ˆ๋‹ค.")
//        });

        // ์œ„์˜ ์ฝ”๋“œ๋ฅผ Methodํ™” ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
        // ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ๋ชจ๋‘ ์„ ํƒํ•˜๊ณ , Command + Option + M์„ ๋ˆŒ๋Ÿฌ์ค€๋‹ค.

        validateDuplicationMember(member);      // ์ค‘๋ณต ํšŒ์› ๊ฒ€์ฆ

        memberRepository.save(member);
        return member.getId();
    } // join() ๋

    private void validateDuplicationMember(Member member) {
        // ์œ„์— ์ฝ”๋“œ ๋ณด๋‹ค ๋” ์ข‹์€ ์ฝ”๋“œ
        memberRepository.findByName(member.getName()).ifPresent(member1 -> {
            throw new IllegalStateException("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํšŒ์› ์ž…๋‹ˆ๋‹ค.");
        });
    } // validateDuplicationMember() ๋

    public List<Member> findMembers() {
        return memberRepository.findAll();
    } // findMembers() ๋

    public Optional<Member> findOne(Long memberId) {
        return memberRepository.findById(memberId);
    } // findOne() ๋

} // Class ๋

 

 

MemoryMemberRepository.java

package hello.hellospring.repository;


import hello.hellospring.domain.Member;

import java.util.*;

//@Repository
public class MemoryMemberRepository implements MemeberRepository{

    private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L;

    @Override
    public Member save(Member member) {
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    } //save () ๋

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id));
    } // findById() ๋

    @Override
    public Optional<Member> findByName(String name) {
       return store.values().stream().filter(member -> member.getName().equals(name)).findAny();
    } // findByName () ๋

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    } // findAll() ๋

    // Test๊ฐ€ ํ•˜๋‚˜ ๋๋‚  ๋•Œ๋งˆ๋‹ค Repository๋ฅผ Clear ์‹œ์ผœ์ฃผ๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ (MemoryMemberRepositoryTest์˜ afterEach()์—์„œ ํ˜ธ์ถœ)
    public void clearStore() {
        store.clear();
    }
} // Class ๋

 

๊ธฐ์กด์— ์ž‘์„ฑํ–ˆ์—ˆ๋˜ Code์—์„œ @Service, @Repository, @Autowired๋ฅผ ์ฃผ์„์ฒ˜๋ฆฌ๋ฅผ ํ–ˆ๊ณ , ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ๊ฒŒ์š”!

 

 

์‹คํ–‰ ๊ฒฐ๊ณผ

/Library/Java/JavaVirtualMachines/jdk-11.0.12.jdk/Contents/Home/bin/java -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=57067:/Applications/IntelliJ IDEA.app/Contents/bin -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8 -classpath /Users/juny/SynologyDrive/๊ฐœ์ธ์ž๋ฃŒ/97.SourceCode/00.Study/00.Inflearn/์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ /hello-spring/out/production/classes:/Users/juny/SynologyDrive/๊ฐœ์ธ์ž๋ฃŒ/97.SourceCode/00.Study/00.Inflearn/์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ /hello-spring/out/production/resources:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-thymeleaf/2.5.3/ac0d6c1779e8a4e77f5be14e38150bf3dd1339fe/spring-boot-starter-thymeleaf-2.5.3.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-web/2.5.3/2cb23f2928177eeb9be81036623f4350a86a433/spring-boot-starter-web-2.5.3.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter/2.5.3/2e16fb3d63961548468a2cd70015d4b1be968fd4/spring-boot-starter-2.5.3.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.thymeleaf/thymeleaf-spring5/3.0.12.RELEASE/aa640b214411978a23cbe271c3fb9569d1bda608/thymeleaf-spring5-3.0.12.RELEASE.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.thymeleaf.extras/thymeleaf-extras-java8time/3.0.4.RELEASE/36e7175ddce36c486fff4578b5af7bb32f54f5df/thymeleaf-extras-java8time-3.0.4.RELEASE.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-json/2.5.3/10336b02e83756f916c0d9510555046cacfc2005/spring-boot-starter-json-2.5.3.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-tomcat/2.5.3/bedcf69b9e83a0744d93e5672320039b55deffd/spring-boot-starter-tomcat-2.5.3.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework/spring-webmvc/5.3.9/c3cd1f0bba2658995e887d2f0011ab9bd3da1773/spring-webmvc-5.3.9.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework/spring-web/5.3.9/88c920ec1bda67fea04daa8e16165777440df473/spring-web-5.3.9.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-autoconfigure/2.5.3/f03d7e9102d93ab25110da850be9facf11818a0b/spring-boot-autoconfigure-2.5.3.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot/2.5.3/e25d2de9e166a8bbbfae633fc03220ab36ac19a9/spring-boot-2.5.3.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-logging/2.5.3/a3a2057be09b4105ecf2e7e3097e0e3fe2eb2684/spring-boot-starter-logging-2.5.3.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/jakarta.annotation/jakarta.annotation-api/1.3.5/59eb84ee0d616332ff44aba065f3888cf002cd2d/jakarta.annotation-api-1.3.5.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/5.3.9/cfef19d1dfa41d56f8de66238dc015334997d573/spring-core-5.3.9.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.yaml/snakeyaml/1.28/7cae037c3014350c923776548e71c9feb7a69259/snakeyaml-1.28.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.thymeleaf/thymeleaf/3.0.12.RELEASE/de1865b0d58590a50c33900115a293335dd8ef25/thymeleaf-3.0.12.RELEASE.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/1.7.32/cdcff33940d9f2de763bc41ea05a0be5941176c3/slf4j-api-1.7.32.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.12.4/b1174c05d4ded121a7eaeed3f148709f9585b981/jackson-datatype-jsr310-2.12.4.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.module/jackson-module-parameter-names/2.12.4/87c4e9a3302f0fafe4e5587f9c27d22847d8fe00/jackson-module-parameter-names-2.12.4.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jdk8/2.12.4/858a1e1b677cbafd3b100d5154f491a7051401c/jackson-datatype-jdk8-2.12.4.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-databind/2.12.4/69206e02e6a696034f06a59d3ddbfbba5a4cd81/jackson-databind-2.12.4.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-websocket/9.0.50/eb8d0bedeb2a9ed61ea3b3790055e937e52898a3/tomcat-embed-websocket-9.0.50.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-core/9.0.50/14307c487516ab3526213a1205c5243b0c484e8d/tomcat-embed-core-9.0.50.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-el/9.0.50/ee4e14e128bf6ffe7650c7a5d8cedf97fb36d91b/tomcat-embed-el-9.0.50.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework/spring-context/5.3.9/887f4579ade4f47cf0102856f4f4c88eda8ec9d7/spring-context-5.3.9.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework/spring-aop/5.3.9/9bcad31a74e60d205500dd67d2220bd0195c63f8/spring-aop-5.3.9.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework/spring-beans/5.3.9/48600db2cb1abc0f7ef2b073f0c1abd78a83bcfc/spring-beans-5.3.9.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework/spring-expression/5.3.9/f5ca763cfb9d62d196efd5d25e8daca7d555ed75/spring-expression-5.3.9.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.2.4/f3bc99fd0b226065012b24fe9f808299048bab54/logback-classic-1.2.4.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-to-slf4j/2.14.1/ce8a86a3f50a4304749828ce68e7478cafbc8039/log4j-to-slf4j-2.14.1.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.slf4j/jul-to-slf4j/1.7.32/8a055c04ab44e8e8326901cadf89080721348bdb/jul-to-slf4j-1.7.32.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.springframework/spring-jcl/5.3.9/622eb12c98768b6d3acc71ce06bac8b332607a10/spring-jcl-5.3.9.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.attoparser/attoparser/2.0.5.RELEASE/a93ad36df9560de3a5312c1d14f69d938099fa64/attoparser-2.0.5.RELEASE.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.unbescape/unbescape/1.1.6.RELEASE/7b90360afb2b860e09e8347112800d12c12b2a13/unbescape-1.1.6.RELEASE.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-annotations/2.12.4/752cf9a2562ac2c012e48057e3a4c17dad66c66e/jackson-annotations-2.12.4.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-core/2.12.4/6a1bd259b6c4e3f9219ec8ec0be55ed11eed0c/jackson-core-2.12.4.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-core/1.2.4/5f429ee58dbacf9040f846f1218c36ca6e851596/logback-core-1.2.4.jar:/Users/juny/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.14.1/cd8858fbbde69f46bce8db1152c18a43328aae78/log4j-api-2.14.1.jar hello.hellospring.HelloSpringApplication

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.3)

2021-08-07 03:17:00.400  INFO 1407 --- [           main] h.hellospring.HelloSpringApplication     : Starting HelloSpringApplication using Java 11.0.12 on hongsejun-ui-MacBookAir.local with PID 1407 (/Users/juny/SynologyDrive/๊ฐœ์ธ์ž๋ฃŒ/97.SourceCode/00.Study/00.Inflearn/์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ /hello-spring/out/production/classes started by juny in /Users/juny/SynologyDrive/๊ฐœ์ธ์ž๋ฃŒ/97.SourceCode/00.Study/00.Inflearn/์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ /hello-spring)
2021-08-07 03:17:00.406  INFO 1407 --- [           main] h.hellospring.HelloSpringApplication     : No active profile set, falling back to default profiles: default
2021-08-07 03:17:01.880  INFO 1407 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-08-07 03:17:01.892  INFO 1407 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-08-07 03:17:01.892  INFO 1407 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.50]
2021-08-07 03:17:01.976  INFO 1407 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-08-07 03:17:01.976  INFO 1407 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1437 ms
2021-08-07 03:17:02.042  WARN 1407 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberController' defined in file [/Users/juny/SynologyDrive/๊ฐœ์ธ์ž๋ฃŒ/97.SourceCode/00.Study/00.Inflearn/์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ /hello-spring/out/production/classes/hello/hellospring/controller/MemberController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'hello.hellospring.service.MemberService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2021-08-07 03:17:02.045  INFO 1407 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2021-08-07 03:17:02.059  INFO 1407 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-08-07 03:17:02.077 ERROR 1407 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in hello.hellospring.controller.MemberController required a bean of type 'hello.hellospring.service.MemberService' that could not be found.


Action:

Consider defining a bean of type 'hello.hellospring.service.MemberService' in your configuration.


์ข…๋ฃŒ ์ฝ”๋“œ 1(์œผ)๋กœ ์™„๋ฃŒ๋œ ํ”„๋กœ์„ธ์Šค

 

Controller์—์„œ MeberService๊ฐ€ DI๊ฐ€ ์•ˆ๋˜์—ˆ๋‹ค๋ณด๋‹ˆ ์ด๋ ‡๊ฒŒ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๊ณ  ๋‚˜์˜ค๋Š” ๊ฒƒ์ด์—์š”.

 

๋จผ์ € ์ฃผ๋‹ˆํ•˜๋ž‘์€ main / java / hello / hellospring / SpringConfig.java ๋ผ๋Š” Class๋ฅผ ๋งŒ๋“ค ๊ฒƒ์ด์—์š”.

 

package hello.hellospring;

import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfing {

    // @Bean : Bean์„ ๋‚ด๊ฐ€ ์ง์ ‘ ๋งŒ๋“ค๊ฒ ๋‹ค๋Š” ์˜๋ฏธ; ์Šคํ”„๋ง์€ ์ด๊ฒƒ์„ ๋ณด๊ณ , Bean์„ ๋“ฑ๋กํ•˜๋ผ๋Š” ๋ช…๋ น์œผ๋กœ ์ธ์‹
    @Bean
    // ์•„๋ž˜ Method๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ Bean์— ๋“ฑ๋ก
    public MemberService memberService() {
        // MeberService๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ memberRepository๋ฅผ Spring Bean์— ๋“ฑ๋ก ๋œ ์ฃผ์ž…ํ•˜์—ฌ ์ค€๋‹ค.
        return new MemberService(memberRepository());
    } // memberService() ๋

    @Bean
    public MemoryMemberRepository memberRepository() {
        return new MemoryMemberRepository();
    } // memberRepository() ๋
} // Class ๋

 

์ฐธ๊ณ  :
๊ฐ•์˜์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ

์•„๋ž˜ ๋‚ด์šฉ์ฒ˜๋Ÿผ MemberRepository Method๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, Interface๋กœ ์ƒ์„ฑํ•˜๊ณ , return๊ฐ’์— ๊ตฌํ˜„์ฒด๋ฅผ new๋กœ ๋งŒ๋“ค์–ด์„œ ํ•˜๋ ค๊ณ  ํ•˜๋ฉด Error ๋ฐœ์ƒ

 

package hello.hellospring;
    import hello.hellospring.repository.MemberRepository;
    import hello.hellospring.repository.MemoryMemberRepository;
    import hello.hellospring.service.MemberService;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class SpringConfig {
  
         @Bean
        public MemberService memberService() {
            return new MemberService(memberRepository());
        }
        
        @Bean
        public MemberRepository memberRepository() {
          	return new MemoryMemberRepository();
    	}
}

 

 

์ด๋ ‡๊ฒŒ Error๊ฐ€ ๋‚˜๋Š” ๊ฒƒ์ด์—์š”. ์œ„์˜ ๋ถ€๋ถ„์€ ๋‹ต์„ ์ฐพ์œผ๋ฉด ์•„๋ž˜์— ์ถ”๊ฐ€๋กœ ๋‚ด์šฉ์„ ๋‹ฌ์•„ ๋†“๋„๋ก ํ• ๊ฒŒ์š”!

 

@Configuration๊ณผ @Bean์„ ์‚ฌ์šฉํ•˜๋ฉด ์ง์ ‘ Java Code๋กœ Spring Bean์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

 

Spring Framwork์—์„œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ XML๋กœ๋„ ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ตœ๊ทผ์—๋Š” ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ,

์œ„์˜ ๋ฐฉ์‹์ฒ˜๋Ÿผ Annotaion์„ ๋งŽ์ด ํ™œ์šฉ ํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค!

 

DI์—๋Š” Filed, ์ƒ์„ฑ์ž, Setter ์ฃผ์ž… ์ด 3๊ฐ€์ง€์˜ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

 

 

  • Filed ์ฃผ์ž…
public class FiledDependencyInjection {

	@Autowired	Test test;

}

 

  • Setter ์ฃผ์ž…
public class SetterDependencyInjection {

	Test test;
    
    public void setTest(Test test) {
      this.test = test;
    } // setTest() ๋

} // Class ๋

 

  • ์ƒ์„ฑ์ž ์ฃผ์ž…
public class ConstructorDependencyInjection {

	Test test;
    
    public ConstructorDependencyInjection(Test test) {
      this.test = test;
    } // setTest() ๋

} // Class ๋

 

์˜์กด ๊ด€๊ณ„๊ฐ€ ์‹คํ–‰์ค‘์— ๋™์ ์œผ๋กœ ๋ณ€ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์—†์Šต๋‹ˆ๋‹ค!
๊ทธ๋ง์€ ๋ฌด์—‡์ด๋ƒ๋ฉด Run Time (Web์ด ๋™์ž‘์ค‘์ธ ์ƒํƒœ์—์„œ ์ฃผ์ž…ํ•ด์•ผ ํ•  ๋‚ด์šฉ์ด ๋ณ€๊ฒฝ๋  ์ผ์€ ์—†๋‹ค๋Š” ์˜๋ฏธ ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ๊ถŒ์žฅํ•˜๋Š” ๊ฒƒ์ด์—์š”!

์ƒ์„ฑ์ž ์ฃผ์ž…์€ ์ฒ˜์Œ ์‹คํ–‰ ๋‹จ๊ณ„์—์„œ๋งŒ ํ˜ธ์ถœ์ด ๋˜์–ด ๋™์ž‘ํ•˜๊ณ , ์ด ํ›„์—๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค!

 

์š”์ฆ˜ ์‹ค๋ฌด์—์„œ๋Š” ์ฃผ๋กœ ์ •ํ˜•ํ™”๋œ Controller, Service, Repository ๊ฐ™์€ ๊ฒƒ๋“ค์€ Component Scna์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด์š”!

์ด๋ฏธ ์šฐ๋ฆฌ๊ฐ€ ํ™•์ธ ํ•ด ๋ณด์•˜๋“ฏ์ด Annotation๋งŒ ์žˆ์œผ๋ฉด ์•Œ์•„์„œ ํ•ด์ฃผ๋‹Œ๊นŒ ํŽธ๋ฆฌํ•จ ๋•Œ๋ฌธ์ด๊ฒ ์ง€์š”?

ํ•˜์ง€๋งŒ, ์ •ํ˜•ํ™” ๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜, ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ตฌํ˜„ Class๊ฐ€ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์œ„์—์„œ ํ–ˆ๋“ฏ์ด ์„ค์ •์„ ํ†ตํ•ด Spring Bean์„ ๋“ฑ๋กํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด์—์š”.

 

์ง€๊ธˆ ์šฐ๋ฆฌ๊ฐ€ ์ด๊ฑธ ๊ณต๋ถ€ํ•˜๋Š” ๊ฒƒ์€ ์ด ์‹ค์Šต์ด DB๊ฐ€ ์ •ํ•ด์ง€์ง€ ์•Š์€ ๊ฐ€์ƒ์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ์ž„์‹œ๋กœ Memory Repository๋ฅผ ์‚ฌ์šฉ์ค‘์ธ๋ฐ, ์ด๊ฒƒ์„ ๋‹ค๋ฅธ Repository๋กœ ๋ณ€๊ฒฝํ•  ๊ฒƒ์ด๊ณ , ์œ„์™€ ๊ฐ™์ด Java Code๋กœ Spring Bean์„ ์„ค์ •ํ•˜๋ฉด Service, Repository, Controller๋ฅผ ๊ฑด๋“ค์ง€ ์•Š๊ณ ,

SpringConfig์˜ Return ๊ฐ’์— ์•ฝ๊ฐ„๋งŒ ์ˆ˜์ •์„ ํ•ด์ฃผ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์šฐ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

 

์ฃผ์˜ํ•  ์ ์€ @Autowired๋ฅผ ํ†ตํ•œ DI๋Š” Spring์ด ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด์—์„œ๋งŒ ๋™์ž‘์„ ํ•œ๋‹ค๋Š” ๊ฒ๋‹ˆ๋‹ค. Spring Bean์œผ๋กœ ๋“ฑ๋กํ•˜์ง€ ์•Š๊ณ , ๋‚ด๊ฐ€ ์ง์ ‘ ์ƒ์„ฑํ•œ ๊ฐ์ฒด์—์„œ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์  ๊ผญ ์•Œ์•„๋‘ฌ์•ผ ํ•˜๋Š” ๊ฒƒ์ด์—์š”!

 

 


 

์ฃผ๋‹ˆํ•˜๋ž‘์˜ ๊ธ€์ด ๋งˆ์Œ์— ๋“œ์…จ๋‚˜์š”? ๊ตฌ๋…๊ณผ ๊ณต๊ฐ! ๊ทธ๋ฆฌ๊ณ , ๋Œ“๊ธ€์€ ์ฃผ๋‹ˆํ•˜๋ž‘์—๊ฒŒ ๋งŽ์€ ํž˜์ด ๋ฉ๋‹ˆ๋‹ค

728x90
๋ฐ˜์‘ํ˜•