[Spring] 의존성 주입하기

Martin the dog·2023년 6월 28일

스프링 복습하기

목록 보기
1/15

스프링을 사용하지 않으면, 우리는 클래스에서 각 멤버 변수들을 초기화 해주기 위해 다음과 같이 해줘야 한다.

public class A{
    public void printHello(){
    	System.out.println();
   }
}
///다른곳에 정의된 class
public class B{
	public A a;
    public B(){
    	this.a = new A();
    }
}

하지만 이런 방법은 유저가 직접 정의를 해줘야 하고 만약 저 A를 생성하여 사용하는 클래스들이 많은 상황에서 a에 대입되는 방법이 바뀌면 저 a를 수정해 주기 위해서 많은 시간과 노력이 들어갈 것이다.

이를 방지하고자 스프링에서는 @Bean, @Component, @Configuration으로 스프링에서 객체들을 관리하고자 한다. 위 코드를 스프링이 자동으로 설정하는 방법은 다음과 같다.
1. 클래스 A를 생성해주는 메서드를 포함한 configuration 클래스를 정의한다.

@Configuration
public class aConfiguration{
	@Bean
    public A setA(){
    	return new A();
    }
}
  1. 이제 Class B에서 a에 @Autowired를 달아주어 a에 값을 주입한다.
public class B{
	@Autowired
    public A a;
    ...etc...
 }

이렇게만 해주면 스프링에서는 다음과 같은 방식으로 작동하여 a에 값을 주입해준다.
1. @Autowired를 발견한 스프링은 해당 클래스를 리턴하는 빈을 찾는다.
2. 맞는 빈을 찾으면 해당 빈에서 리턴하는 값으로 해당 값을 주입해준다.

이때 빈에서도 다른 빈함수를 가져와 초기화 할 수 있다.

@Configuration
class helloConfiguraion{
	@Bean
    public A returnA(){
    	return new A();
    }
    @Bean 
    public B returnB(){//다른 빈 함수를 가져와 사용 하는 것
    	return new B(return A());
    }
    
    @Bean(name = "anotherBean") <=원래는 빈의 이름은 함수의 이름으로 초기화가 이루어 지는데 이렇게 따로 지정할 수 있다.
    public C returnC(){
    	return new C();
    }
    
    @Bean
    //이렇게 빈함수의 파라미터명이 다른 빈함수의 이름과 일치하면 해당 파라미터에 일치하는 빈함수에서 만들어진 결과를 맵핑시켜준다. 
    public D returnD(A returnA,B returnB,C anotherBean)
    	return D(returnA,returnB,anotherBean);
    }
}

그런데 만약 다음과 같은 경우는 어떨까?

@Configuration
public class aConfiguration{
	@Bean
    public A setA(){
    	return new A();
    }
    @Bean
    public A setAwithParam(){
    	return new A("asdf");
    }
}

둘다 A 클래스를 리턴하기 때문에 어떤 함수를 사용해야할 지 고민에 빠진 스프링은 오류를 내뱉는다. 해당 문제를 해결할 수 있는 방법은 다음과 같다.
1. @Primary로 우선 실행될 빈을 설정한다.
2

어디 클래스
@Component test{
	@Bean
    @Qualifier("name")
    public C returnC(){
       return C
    }
    @Bean 
    public C returnNewC(){
    	return new C();
    }
@Autowired
@Qualifier(name="NAME")

를 이용하여 빈 이름이 NAME인 빈을 통해 초기화 한다.
이렇게 빈으로 의존성을 주입해주면 다음과 같은 장점이 있다.
1. 수정사항이 있을 시 사용자의 노고가 줄어든다.

class B {
	public A a;
    public B(){
    	a=new A();
    }
 }

이렇게 A를 사용하고 있는 클래스가 수백개가 넘어갈 때 만약 a = new A()를 a = new A("asdf")로 바꿔주면 존재하는 만큼 바꿔주어야 하지만 스프링 빈은 저 A를 만드는 함수만 바꿔주면 되기 때문에 빠른 작업이 가능해진다.
2. 범위 지정이 쉬워진다.
설정에 사용되는 객체의 경우 하나의 설정값으로 전체 클래스에 적용시켜야 하는 경우가 있다. 기존에 직접 new해주는 방식으로는 매우매우 어렵지만 스프링에서는 단순하게
@Bean
@Scope("스코프 범위 설정값")
를 해주면 된다.
이때 범위 설정값에는
Singletone: 스프링 전역에 하나만 존재
prototype: 여러개 존재 가능
request: HTTP request의 생명주기 안에 단 하나의 객체만 존재한다.
session: Sessoiondml 생명주기에서 단 하나의 객체만 존재한다.

이렇게 특정 상황에서 특정 공간에 하나만 존재하거나 여러개 존재하게 설정해줄 수 있다.

이러한 방법을 통해 우리는 스프링 프레임워크를 사용하여 의존성을 주입할 수 있다.

profile
Happy Developer

0개의 댓글