클래스와 객체부터 IoC까지

기 원·2025년 4월 16일

Java를 Spring 처럼!

목록 보기
1/5

Java를 Spring 처럼! - 클래스와 객체부터 IoC까지


이 시리즈를 시작한 이유

"스프링이 혹은 자바가 너무 어려워요..."

누군가 제게 이런 말을 하였을때 똑부러지게 알려줄 수 있다면 좋겠지만...

실상은 "저도 찾아 봐야겠어요...", "찾아보고 알려드릴께요!" 라고 대답하는 현실이 너무 안타까웠습니다.

저도 기본기를 다지고, 겸사겸사 누군가에게 도움이 될 방법이 없을까?

그래서 준비했습니다! Java로 직접 만들어보면서 '스프링의 구조'를 흉내내보고, 개념을 몸으로 느껴보는 시리즈!!

1. 해당 아이디어는 내일배움캠프의 다락방 강의를 듣고 차용했습니다!
2. 사용한 이모지는 GetEmoji 에서 사용하였습니다!
3. 잘못된 설명이 있다면 댓글로 알려주세요...

이 시리즈는 진짜 기본부터, 클래스와 객체부터 시작해서, 나중에 우리가 흔히 쓰는 @Service, @Autowired 같은 어노테이션이 왜 필요한지까지 이어질 예정입니다.


1. 클래스와 객체: 진짜로 이해하기

☝🏻 클래스란?

클래스는 설계도입니다. 객체는 실체(인스턴스)입니다.

public class User {
    String name;
    int age;
}

User user = new User();
user.name = "기원";
user.age = 20;

→ 여기서 User는 클래스고, user는 객체입니다.
대문자 U와 소문자u의 차이!

☝🏻 왜 나누는 걸까?

  • 어떤 데이터(User)를 다룰지 정의하는 게 클래스
  • 진짜 메모리에 올라가서 살아 움직이는 게 객체

2. 메서드: 객체의 동작

public class User {
    String name;
    void sayHello() {
        System.out.println("안녕하세요, 저는 " + name + "입니다.");
    }
}
User u = new User();
u.name = "영희";
u.sayHello();

→ 객체는 데이터 + 동작(메서드)를 함께 가짐 = 캡슐화!!


3. 객체 지향의 핵심 - "서로가 서로를 부른다"

서비스를 구성할 때는 보통 한 객체가 다른 객체를 사용합니다.

public class UserService {
    public void register() {
        System.out.println("회원가입 로직 실행");
    }
}

public class UserController {
    UserService userService = new UserService();

    public void joinUser() {
        userService.register();
    }
}

이 구조는!? - 스프링의 Controller → Service 호출 구조와 비슷하다! 라는걸 알 수 있습니다.


4. 그런데 왜 new 는 쓰지 말라는 걸까?

아까 위 코드에서 UserController는 내부에서 new UserService()로 직접 생성했었죠?

바로 UserService userService = new UserService(); 이 부분!!

⚠️ 문제점

  • 테스트하기 어려워요! → Service를 다른 걸로 바꾸고 싶을 때 힘듭니다.
  • 결합도가 높아져요! → 한 클래스가 다른 클래스에 너무 의존합니다.

💬 해결 방법: 생성자 주입

public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    public void joinUser() {
        userService.register();
    }
}

그리고 실행부에서는?

UserService userService = new UserService();
UserController controller = new UserController(userService);
controller.joinUser();

→ 이게 바로 스프링에서 말하는 의존성 주입(DI)의 시작입니다!

5. IoC - 제어의 역전

❗️ 지금까지는 누가 객체를 만들었죠?

UserService userService = new UserService();
UserController controller = new UserController(userService);

→ 정답은!? : 우리가 직접 만들고, 조립해서 사용했습니다!
즉, "제어권이 우리에게" 있었던 겁니다.


‼️ 반면 스프링에서는?

@Controller
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

→ 여기에선 UserService를 우리가 new 하지 않았어요!
스프링이 알아서 만들고 넣어줬습니다! (똑똑해...)


💭 그래서 등장한 개념 - IoC (제어의 역전)

Inversion of Control
"객체를 생성하고 연결하는 책임을 개발자가 아니라 프레임워크에게 넘긴다" 쉽게 짬때린다!

  • 지금까지는 우리가 직접 new로 만들었지만
  • 스프링에서는 Container가 대신 객체를 만들고, 주입해줍니다.

그러면? 우리는 객체를 "요청"만 하고,
"어떻게 만들어지는지는 관심 없다! 즉 내가 알빠냐?" → 이것이 IoC 철학입니다.

아직 잘 모르겠다 하신다면, 예를 들어들이겠습니다.

우리가 직접 new를 하는건 → 내가 밀가루 사고, 반죽하고, 오븐에 구워서 크로아상을 만들어 먹는것!
IoC → 빵집에 크로아상을 주문해서 사 먹는것!

Spring은 빵집이고, 우리는 "크로아상 하나요~" 요청만 하면 되는거죠!

그래서 Ioc와 DI는 무슨 차이냐!?

  • Ioc는 철학, DI는 IoC를 구현하는 기술적 방법

6. 챕터 정리

개념의미예시
클래스설계도User
객체실체new User()
메서드동작sayHello()
의존성다른 객체를 사용하는 것Controller → Service
생성자 주입외부에서 객체를 받아서 쓰는 방식new UserController(service)
IoC객체를 직접 만들지 않고 외부에서 주입Spring이 대신 new 해줌
profile
노력하고 있다니까요?

1개의 댓글

comment-user-thumbnail
2025년 4월 18일

71 0님 감사히 잘 읽었습니다! 😆 n독 했다니까여!!!

답글 달기