Tiny Bunny [Spring] @ 어노테이션 설정 - 솜님의 블로그
솜님의 블로그
카테고리
작성일
2024. 10. 6. 04:15
작성자
겨울솜사탕

@ 어노테이션 설정

 

.xml에 어노테이션을 사용하고 싶어서 컴파일 전 @ 어노테이션 있는지 확인해 달라는 설정이 필요하다.

(파일 위에 달려있는 어노테이션은 컴파일 전(메모리에 옮기기 전)에 본다)

 

 

스키마 추가가 필요함!

<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-4.2.xsd">

위 내용을 그대로 사용하면 된다.

(하나라도 틀리면 동작하지 않음!)

 

추가로 beans 안쪽에 아래의 코드도 필요하다.

<context:component-scan base-package="test" />

위 코드는 스캔하는 범위를 지정하는 코드이다.

(test 패키지만 스캔함)

 

이를 실행했을 때 나오는 순서는 test 패키지의 파일 순서대로!

 

// applicationContext.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-4.2.xsd">
                  

	<!-- 스캔할 범위를 설정해준다. -->
	<context:component-scan base-package="test" />
    
</beans>

 

 


Iphone.java에 어노테이션 설정을 추가한다.

package test;

import org.springframework.stereotype.Component;

@Component("apple") //어노테이션 설정 추가
public class Iphone implements Phone {

	private Watch watch; 

	public Iphone() {
		System.out.println("아이폰 객체 생성 01");
	}
	
    
	@Override
	public void powerOn() {
		this.watch.powerOn();
	}

	@Override
	public void powerOff() {
		this.watch.powerOff();
	}
	
    
	public Watch getWatch() {
		return watch;
	}

	public void setWatch(Watch watch) {
		this.watch = watch;
	}
	
}

@Component("apple")는

new의 역할 == <bean>의 역할을 한다.

("apple") 는 <bean>에서 id이다.

 

Iphone apple = new Iphone();

== <bean class="Iphone" id="apple" />

== @Component("apple")

 

컴포넌트 == Bean == 모듈 == 패키지 == 위젯

               == 리팩토링 결과물

               == 함수화 == 메서드화 << 얘네는 좁은 의미의 리팩토링

 

 

 

// Client.java

package test;

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

public class Client {

	public static void main(String[] args) {

		// 스프링 컨테이너 factory = new 스프링컨테이너();
		AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");  //GenericXmlApplicationContext == 아무 의미 없는 실습용 메서드임

		Phone phone = (Phone)factory.getBean("apple"); // 다운캐스팅
		// Bean == 자바객체 == 객체 == POJO
		// 객체를 요청하다 == look up

		phone.powerOn();
		phone.powerOff();

		factory.close();

	}
}

Client에서 위처럼 powerOn / powerOff를 하려고 한다.

 

코드를 따라가보면 Watch로 power 동작을 한다.

하지만 현재 watch가 new 되어있지 않다.

따라서 watch 클래스 파일에도 new를 해주는 @Component 어노테이션을 달아줘야 한다.

하지만 private Watch watch; 에게 AppleWatch가 필요하다는 사실을 컨테이너는 모른다.

-> 이전에는 그래서 Setter 주입이나 생성자 주입을 했다.

    이 의미는? 의존 주입이 필요하다는 의미! ( == DI 대상이다)

 

그래서 멤버변수 위에 @ 어노테이션을 달아준다.

@Autowired
@Qualifier("aw")
private Watch watch;

@Autowired를 달면 메모리의 자료형(타입)을 인지해서 주입을 한다.

 

만약 의존성이 여러개라면? (워치도 있고, 아이패드도 있고..)

하나하나 @Autowired를 달아줘야 한다.

어노테이션 하나당, 멤버변수 하나!!

 

그런데 @Autowired는 메모리의 타입을 인지해서 주입하는데, 현재 무슨 자료형인지 알 수 없다.

그래서 @Qualifier("aw")를 같이 달아야 한다.

 

🍀정리
1. <bean> 대신에 @Component로 객체 new
2. DI(의존주입) 기존에는 Setter 주입, 생성자 주입을 사용했는데 지금은 @Autowired로 주입
3. @Autowired는 메모리의 자료형만 참고하기 때문에 DI 모호성 에러 발생하기 쉬움
4. @Qualifier 객체명 참고하는 어노테이션을 달아줘야 한다.

 

여기서 TIP!

@Qualifier는 잘 쓰이지 않음.

-> 동일한 타입의 객체를 메모리에 여러 개 생성했다는 뜻이라서 성능에 좋지 않다.

     따라서 성능에 예민한 프로그램들은 이걸 사용하지 않는다.

 

대신!

.xml에서

<bean class="test.AppleWatch" id="aw" /> 

를 사용하고, @Qualifier는 지워준다.

(섞어서 사용한다!)

 

이를 사용할 때,

<bean class="test.AppleWatch" id="aw" />

<bean class="test.GalaxyWatch" id="gw" />

이렇게 두 개 다 사용하게 되면 DI 모호성 에러 발생하기 때문에, 객체 생성이 필요한 bean만 작성한다.

 

'Spring' 카테고리의 다른 글

[Spring] DispatcherServlet  (0) 2024.10.07
[Spring] Spring의 구조와 Service  (0) 2024.10.06
[Spring] Spring 내용 정리  (0) 2024.10.06
[Spring] 의존성 주입  (0) 2024.10.06
[Spring] 결합도가 높은 프로젝트의 형태  (1) 2024.10.03