[Spring] 빈 등록 방법

이신영·2023년 8월 30일
1

Spring

목록 보기
4/16
post-thumbnail

저번 글에 빈이랑 스프링 컨테이너라는 말이 나와서그런데 이것도 정리해보면 좋겠다~ 싶어서 정리해보자!


스프링 컨테이너

스프링 컨테이너는 자바 객체의 생명주기를 관리하며, 생성된 자바 객체들에게 기능을 제공하는 역할을한다. 여기서 말하는 자바의 객체란 빈(Bean)이다.?

빈(Bean)을 등록하는 방법을 알기전에 누가 빈을 관리하나? 결론부터 말하자면 스프링은 IoC 컨테이너로 빈을 관리한다.

IoC?

Don't call us, we'll call you.

Inversion of Control(IoC)는 직역하자면 제어의 역전이다. 이게 뭔지 간단하게 설명해보자면, 우리는 스프링 프레임워크를 쓸 때 Controller, Service같은 객체들의 동작은 직접 구현은 하지만 얘네가 언제쓰일지는 상관하지않는다. 그럼 객체들이 언제 생성되고 어떻게 쓰일 지는 누가 담당할까? 그게 바로 스프링 컨테이너다. 즉, 개발자가 코드의 흐름과 제어를 관리하는 대신에 스프링 컨테이너가 제어의 권한을 가진다!

이전시간에 정리한 DI도 결국은 IoC의 한가지 예시라고 볼 수 있겠다.


빈 등록 방법

이제 본격적으로 빈을 등록하는 방법에 대해 알아보자


XML로 등록하기

XML 파일에 빈 등록

<!-- applicationContext.xml -->

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- UserService 빈 등록 -->
    <bean id="userService" class="com.example.UserService">
        <!-- UserRepository 의존성 주입 -->
        <property name="userRepository" ref="userRepository"/>
    </bean>

    <!-- UserRepository 빈 등록 -->
    <bean id="userRepository" class="com.example.UserRepository"/>

</beans>

빈 사용

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyApp {
    public static void main(String[] args) {
        // 스프링 컨테이너 생성 및 설정 파일 로드
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 빈 가져오기
        UserService userService = context.getBean("userService", UserService.class);
        UserRepository userRepository = context.getBean("userRepository", UserRepository.class);

        // 빈 사용
        userService.setUserRepository(userRepository);
        userService.doSomething();
    }
}

위의 방법이 초기의 방법이다..! 새삼 편해진게 느껴지는군.. 근데 아직 위의 방법도 자주 쓰인다네 😅


이를 해결해주는 스프링의 component scan 기능이 추가된 뒤로는 좀 더 간편해졌다

Component Scan 활용

<!-- applicationContext.xml -->

<context:component-scan base-package="lsy.code.sample" />

component Scan으로 어노테이션이 등록된 패키지안에 bean 클래스를 만들어서 자동으로 빈이 등록될수있게됨

package lsy.code.sample;

@Component
public class ProductService {
    
}

@Component
public class ProductController {
    private final ProductService productService;
    
    @Autowired
    public ProductController(ProductService productService) {
        this.productService = productService;
    }
    
    
}

여기서 @Component 어노테이션은 자동으로 빈이 등록될 수 있게하는 어노테이션이고 위처럼 다 @Component를 사용해도되지만 Entity, Service, Controller를 명시적으로 구분할수있도록 @Entity, @Service, @Controller를 사용하면 좋다~

@Service
public class ProductService {
    // ProductService의 비즈니스 로직
}

@Controller
public class ProductController {
    private final ProductService productService;

    @Autowired
    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    // Controller의 요청 처리 메서드
}

요렇게말이죠

근데 아직도 좀 불편한 감이 없지않죠?


Config 활용

@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
    
    @Bean
    public MyController myController(@Autowired MyService myService) {
        return new MyController(myService);
    }
}

@Configuration 어노테이션을 사용한 config파일에서 @Bean을 사용해 빈으로 등록할수있다. 이걸 활용하려면?

@Controller
public class MyController {
    private final MyService myService;
    
    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }
    
    // Controller의 메서드 구현
}

이렇게 쓸수있다


지금까지 방법들은 모두 xml이나 config파일에서 일일이 등록해야하는 문제가 있다. 이걸 해결하기위해 component Scan을 사용할 수 있다!

Component Scan + Config 활용

패키지

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

클래스

@Configuration
@ComponentScan(baseClasses = "exampleApplication.class")
public class AppConfig {
}

@ComponentScan의 속성인 basePackages로 최상단 패키지를 설정하던지 baseClasses으로 최상단 클래스를 설정하여 모든 bean을 스캔하고 등록해줄수있다!

그런데? 이것도 귀찮다??


@SpringBootApplication 활용

@SpringBootApplication
public class exampleApplication {

	public static void main(String[] args) {
		SpringApplication.run(exampleApplication.class, args);
	}

}

@SpringBootApplication 어노테이션은 @ComponentScan + @Configuration이 담겨져있기때문에 따로 config파일이나 컴포넌트스캔이 필요하지않는다!

아마 대부분 위의 방법을 쓰지않을까? 싶을정도로 날로먹을수있다 ㅎㅎ;

profile
후회하지 않는 사람이 되자 🔥

0개의 댓글