Spring

스프링 프레임워크 - 의존 주입(@어노테이션)

뚜벅뚜벅뚜벅이 2022. 7. 11. 19:50
반응형

1. 어노테이션을 이용한 의존주입

클래스 A와 B 가 있을 때

먼저 B는 초기값이 필요한 필드가 있는 클래스이므로 bean을 통해 초기값을 설정해주어야한다.

xml 파일에 bean을 만들어서 컨테이너가 B에 대한 객체의 생명주기를 관리할때 사용할 수있도록 하거나

자바 파일을 만들어서 그 안에 메서드로서 호출해서 객체를 만들수있도록해야한다.

생성할때 초기값을 bean에 설정해준다.

이를 통해 ioc 컨테이너는 B에 대한 생명주기를 관리할 수 있게된다.

package diEx03;

public class B {

	private String name;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}


	public void methodB() {
	
		System.out.println(name+" 객체가 호출하는 메서드 입니다 .");
	}
}

ComponentClass 의 경우 @Component 어노테이션에 대하여 학습하기 위해 만들었다.

B와는 다르게 클래스 내부에 필드가 없고 메서드만 하나 존재하는 상태이다 .

초기값이 필요없으므로 굳이 bean으로 만들어서 관리하기 보다는 @Component 어노테이션을 이용하여 ioc 컨테이너에게 여기에 네가 참고해야할 객체가 있다라고 알려준다.

대신에 xml 문서에 명시를 해주어야한다.

< context:component-scan >태그를 이용하여 해당 패키지를 읽도록 해야한다.

package diEx03;

import org.springframework.stereotype.Component;

//필드가 없이 껍대기만 있는 객체를 가지고 있어라 (클래스 명이 아이디로 지정된다 .아이디 이름은 ioc 컨테이너가 소문자로 바꿔서 객체로 만듬)
@Component
public class ComponentClass {	//어노테이션도 객체와 똑같이 작동하기 때문에 클래스는 이름이 같으면 안된다.  
	
	public void printComponent() {
		System.out.println("필드가 없는 컴포넌트 객체입니다.");
	}
}

클래스 A 에서는 의존주입을 해볼것이다.

의존을 주입받기 위해서는 ioc 컨테이너가 가지고 있어야하기 때문에 xml에 등록을하던 어노테이션을 달아주어야한다. 어노테이션이 달려있어야 컨테이너가 읽는다. 여기서는 클래스에 @Component 어노테이션을 달아준다.

 

package diEx03;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;


@Component
public class A {
	
	//@Component 어노테이션으로 생성된 bean이 아니더라도 ioc 컨테이너가 가지고 있는 모든 빈은 어노테이션을 이용하여 의존을 자동 주입 받을 수 있다. 
	//위의  A 클래스에 달아놓은 어노테이션은 ioc 컨테이너가 읽을 수 있도록 표시를 해둔것이고, xml에 만들어 놓은 bean(B)에 의존성을 주입하려면  여기에도 @Autowired를 선언해야한다. 
	//AutoWired의 경우에는 타입이 일치하는 bean으로 의존성을 주입하기 때문에 Qualifier를 이용해서 아이디 값을 구체적으로 특정할 수 있다. 
	@Qualifier("b1")	//bean을 여기에 주입하는 것
	@Autowired
	private B b;
	
	//@Autowired //필드 자체에 어노테이션을 달아서 의존을 주입할 수 도 있다. (getter, setter 생성안해도됨)
	private ComponentClass c;
	
	public ComponentClass getC() {
		return c;
	}
	//@Qualifier("c")	//2. @Autowired로 타입이 일치하는것만 찾으면 타입이 같은것은 여러개가 있을 수 있기 때문에 @ 을 하나더 추가해서 id를 특정한다. @Qualifier("아이디")
	@Autowired	//1. 타입이 일치하는 bean으로 주입하기 때문에 이름이 달라도 같은 클래스 타입이기 때문에 주입이 된다 .
	public void setC(ComponentClass c) {
		this.c = c;
	}
	
	
	public void printA() {
		b.methodB();
		c.printComponent();	//ComponentClass가 가지고 있는 메서드
		System.out.println("a 객체를 통한 c 출력");
	}
	
	
}

설정된 xml문서이다.

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">





<bean id="b1" class="diEx03.B">
	<property name="name" value="b1"/>
</bean>

<bean id="b2" class="diEx03.B">
	<property name="name" value="b2"/>
</bean>





<!-- xml은 new - spring bean configuration file 으로 생성 -->
<!-- Namespaces 에서 확장(context)-->
<!-- Component -->

<!-- context:component-scan> 태그를 이용하여 해당 패키지 안에 있는 클래스를 로드하며
@Component 어노테이션이 있는 클래스를 bean으로 등록한다. @Component 어노테이션이 어디에있는지 패키지 명을 적는다. ioc컨테이너가 이 문서를 읽고 패키지를 훑는다.   -->
<context:component-scan base-package="diEx03" /> 

<!-- <context:component-scan base-package="diEx03" /> 태그는 여러개써서 다읽으라고 할 수도 있다.  -->
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">





<bean id="b1" class="diEx03.B">
	<property name="name" value="b1"/>
</bean>

<bean id="b2" class="diEx03.B">
	<property name="name" value="b2"/>
</bean>





<!-- xml은 new - spring bean configuration file 으로 생성 -->
<!-- Namespaces 에서 확장(context)-->
<!-- Component -->

<!-- context:component-scan> 태그를 이용하여 해당 패키지 안에 있는 클래스를 로드하며
@Component 어노테이션이 있는 클래스를 bean으로 등록한다. @Component 어노테이션이 어디에있는지 패키지 명을 적는다. ioc컨테이너가 이 문서를 읽고 패키지를 훑는다.   -->
<context:component-scan base-package="diEx03" /> 

<!-- <context:component-scan base-package="diEx03" /> 태그는 여러개써서 다읽으라고 할 수도 있다.  -->
</beans>
실행해보기

package diEx03;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		
		AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationContext.xml");

		ComponentClass c = ctx.getBean("componentClass", ComponentClass.class);
		
		c.printComponent();
		
		//A 객체를 통한 c출력
		A a = ctx.getBean("a",A.class);

		a.printA();
		
	}

}
반응형