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();
}
}
반응형