개발군싹

[Spring]Spring Bean? 본문

Spring

[Spring]Spring Bean?

개발자군싹 2023. 12. 7. 22:54

제어의 역전 IoC(Inversion of Control)

➡️ 일반적으로 자바에서는 각 객체들이 프로그램의 흐름을 결정하고, 각 객체를 직접 생성하고 조작하는 작업을 했다면 Spring에서는 객체의 생성을 Spring이 관리해주며 이전에 사용자가 직접 객체를 생성하였지만 이제는 Spring이 그 권한을 위임 받아 객체의 생명주기를 컨트롤 하는 특징

 

의존성주입 DI(Dependency Injection)

➡️ SpringFramework를 이용하지 않고 로직 구현 시 객체가 필요시 해당 객체를 필요한 시점에 일일이 선언하고 생성해주어야 했지만 객체를 bean으로 등록해두고 해당 시점에 Spring이 알아서 생성, Controller, Service, Dao 등을 MVC 어노테이션을 이용하여 등록해두고 의존 관계에 있는 객체들을 로직 실행에 필요에 따라 자동으로 생성한다.

 

Spring Bean 이란?

➡️ Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라고 부른다. 일반적으로 이전까지는 Class를 생성하고 new 생성자를 이용하여 원하는 객체를 직접 생성 후 사용했지만 Spring에서는 .xml, annotation 을 이용하여 객체를 Spring BeanFactory에 등록해두고 Spring객체가 로직 실행 중 필요에 의해 자동으로 생성해주고 소멸 시키는 관리기능을 하게 한다.

 

생성한 클래스를 Spring bean으로 등록하는 방법

1) xml파일을 이용해서 등록하기 ( <beans:bean> 태그 이용 ) 

 POJO클래스를 bean으로 등록하기

POJO클래스를 bean으로 등록하기 <beans:bean>태그를 이용해서 등록 -> 객체로 생성하고 보관 기본속성 id : spring bean의 이름 -> spring context에서 사용하는 이름 class : 대상이 되는 클래스를 지정하는 속성 -> 패키지명.클래스명
<!-- 기본생성자로 클래스를 생성해서 beanFactory에 저장 -->
<beans:bean id="animal" class="com.bs.spring.testmodel.Animal"/>

* id 속성에는 생성할 객체의 id값을 적고 class 속성에는 해당 객체의 경로를 적어준다.


클래스의 필드에 초기값 세팅하여 생성하기
- 매개변수있는 생성자를 이용해서 세팅
  => <beans:bean>태그의 자식태그로 
    <beans:constructor-arg>태그를 이용
       속성 : index(매개변수 지정값, 0번부터 시작),value(매개변수에 대입할 값)


<beans:bean id="animal2" class="com.bs.spring.testmodel.Animal">
	 	<beans:constructor-arg index="0" value="강아지"/>
	 	<beans:constructor-arg index="1" value="뽀삐"/>
	 	<beans:constructor-arg index="2" value="19"/>
	 	<beans:constructor-arg index="3" value="13.2"/>	 		
</beans:bean>

* index 속성에는 각 생성자의 선언된 매개변수의 순서에 맞게 데이터를 넣어주기위해 0부터 시작하여 index(순번)를 작성한다. value는 해당 객체의 필드의 초기값(생성자를 이용한 세팅)을 설정해준다.


setter를 이용해서 초기값 설정
<beans:property>태그를 이용
속성
name : 필드명
value : 필드에 저장될 값

	 
 <beans:bean id="animal3" class="com.bs.spring.testmodel.Animal">
    <beans:property name="name" value="바둑이"/>
 </beans:bean>

 

* 말그대로 setter를 이용한 초기값 설정이기 때문에 생성자 생성법과 다르게 인덱스 접근이 아닌 setter의 접근(필드명)으로 접근할 수 있다.


생성되는 bean에 일반값을 저장할 때 value속성을 이용
참조형 자료형을 저장할 때는 ref속성을 이용한다. -> bean id값으로 설정
        
 <beans:bean id="p" class="com.bs.spring.testmodel.Person">
    <beans:property name="name" value="뽀삐주인"/>
    <beans:property name="animal" ref="animal2"/>
 </beans:bean>

 

객체의 필드에 참조형 자료형을 저장해야 할 시 ref 속석을 이용하여 해당 데이터를 표기할 수 있다.


2) 일반 클래스를 등록하는 방법 ➡️ @Componet 어노테이션

클래스 상단에 어노테이션으로 @Component 이용

어노테이션을 사용하여 원하는 생성객체에 등록해두면 xml파일에서 <beans:bean id="" class="">로 기본생성자 클래스 생성과 동일한 기능을 가진다.

 

3) 메소드 방식으로 등록하기 ➡️ @Cofiguration 어노테이션

 클래스에 선언된 메소드 선언부에 @Bean 어노테이션으로 객체를 Bean에 등록할 수 있다.

 ※ @Configuration 어노테이션은 클래스 상단에 @Bean 어노테이션은 생성하려는 객체에 

 

4) mvc 기능 클래스 등록 ➡️ @Controller, @Service, @Repository 와 같이 어노테이션을 이용하여 등록할 수 있다.

- MyBeanConfig.java

package com.bs.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.bs.spring.testmodel.Animal;

//Spring bean configuration.xml과 같은 의미
@Configuration
public class MyBeanConfig {
    //spring bean을 설정할 수 있다.
    
    //객체를 반환하는 메소드를 선언하고 @Bean어노테이션 설정한다.
    //메소드명이 bean의 id가 된다.
    @Bean
    public Animal ani() {
	return new Animal("고양이","야옹이",3,8.3);
    }
    
}

 

- Controller.java

private Animal ani;

@Configuration에 등록된 클래스에서 Bean에 등록된 메소드명과 Controller에서 선언한 객체의 변수명이 같으면 Spring이 자동적으로 객체를 생성해준다.


🔥 스프링은 데이터 입력 시 개발자가 선언한 객체의 타입을 가지고 해당 타입에 맞는 bean 객체를 찾는다. 해당 타입을 찾고 id값으로 어떤 데이터를 넣을지 판단하고 id값과 객체 변수가 다를 시 NoUniqueBeanDefinitionException을 발생시키며 존재하는 아이디를 알려준다.

NoUniqueBeanDefinitionException


의존성 주입(DI) 방법

객체 생성하여 데이터 주입 시 servlet-context.xml 파일에서 bean으로 등록된 타입을 찾아서 해당 id값에 맞는 데이터를 찾아 데이터를 주입한다. Spring 프레임워크의 핵심 기술 중 하나가 바로 DI(Dependency Injection,의존성 주입)이다.

 

1) 생성자 주입 (Constructor Injection)

//springbean으로 등록된 객체 이용하기
//필드에서 주입을 받아 이용이 가능하다. ->
//@Autowired

//주입할 객체를 지정하기
@Qualifier("animal")
private Animal a;

//@Autowired
private Animal animal2;

//@Autowired
private Animal animal3;

➡️ @Qualifier() ? 위에서 언급했듯이 bean의 등록된 Id값으로 spring이 객체를 주입할 객체변수를 찾는다. 이는 bean에 등록된 id 속성의 값과 객체 변수의 변수명이 같아야한다는 뜻이다. 하지만 @Qualifier("bean에 등록된 id")를 이용하면 변수명이 다르더라도 id값을 어노테이션에 적어두었기 때문에 spring은 등록된 객체를 이에 맞춰 생성할 수 있다.


2) @Autowired 어노테이션 사용하지않고 생성자로 DI(의존성 주입)

→ 4버전 이상부터 가능 ( 하위 버전은 @Autowired 어노테이션을 반드시 적어주어야 한다. )

public HelloSpring(@Qualifier("animal") Animal a, Animal animal2, Animal animal3) {
        this.a = a;
        a.setAge(3);
        this.animal2 = animal2;
        this.animal3 = animal3;
}

➡️ Controller로 등록된 'HelloSpring' 클래스의 생성자를 이용하여 Controller가 로드 되는 동시에 DI를 할 수 있다.