의존성 주입의 방법
1. bean
- .xml(설정파일) 내에서 객체 생성
- 문제점 : 객체가 많아지면 설정파일의 가독성 하락
- 해결책 : 어노테이션 사용
2. 어노테이션 (@, 애너테이션)
- 클래스에서 bean 등록
- 응집도 향상, 가독성 증가
- 컴파일 하기 전에 작동
어노테이션 의존성 주입
1. 스키마 추가
xmlns:context=http://www.springframework.org/schema/context 추가
xsi:schemaLocation에서
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd 를 추가
<스키마 추가 완료 코드>
<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">
2. component 범위 설정
</context:component-scan base-package="패키지명" > 스캔하는 범위 추가 코드
<context:component-scan base-package="test" />
3. 어노테이션 사용
@Component : <bean>의 역할
- 컴포넌트 == Bean == 모듈 == 패키지 == 위젯 : 넓은 의미의 리팩토링
- 함수화 == 메서드화 : 좁은 의미의 리팩토링
@Autowired : 의존주입(DI) 대상 설정 (자료형만으로)
- 같은 자료형이 두개 이상 있을 때 오류 (의존성 주입 모호성 오류)
※ 1:1 어노테이션 하나 당 멤버변수 하나
@Qualifier : id를 명시해주는 어노테이션
- 의존성 주입 모호성 오류 해결
.xml 에서 <bean> 변경 = 컴파일x = 비용 x
클래스에서 어노테이션 변경 = 컴파일o = 비용o
실습
<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" />
<bean class="test.AppleWatch" id="aw"></bean>
<bean class="test.GalaxyWatch" id="sw"></bean>
</beans>
<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) {
// 스프링 컨테이너 생성, 컨테이너를 구동시키는 코드
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
// Phone phone = factory야.폰객체좀("아이폰");
// 다운캐스팅 (Phone)으로 해줘야한다
// 다운 캐스팅 - 상위객체를 하위객체로 변환
Phone phone1 = (Phone)factory.getBean("apple");
Phone phone2 = (Phone)factory.getBean("samsung");
// Bean == 자바객체 == 객체 == POJO
// 객체를 요청하다.
// == look up
phone1.powerOn();
phone2.powerOn();
phone1.powerOff();
phone2.powerOff();
/*
// new를 1번만 했기때문에 모두 공유
// "싱글톤" 패턴이 유지된다 == 어떠한 객체가 메모리에 하나만 있다.
// 결론) 스프링 프레임워크(컨테이너)는 싱글톤 패턴을 유지시킴
// scope="prototype"의 bean설정을 통해 여러객체를 메모리에 저장 가능
factory.close();
// 결합도가 높은 프로젝트의 형태 >> 유지보수 어려움
// 결합도를 낮추기 위한 방법들
// 1. 오버로딩 vs [오버라이딩] == 오버라이딩을 강제해야한다 == Interface 사용
// 함수명 중복정의 허용
// 메서드 시그니쳐가 다르면
// 함수명이 같아도 된다!
// 상속 관계와 무간
// 메서드 재정의
// 메서드 시그니쳐가 같아야함
// 상속관계 O
// 2. 개발 패턴 활용하기
// 팩토리 패턴
// ㅇㅇ객체가 필요해. 하고 부탁하면,
// 해당 객체를 주는 패턴을 의미함
// ex) HandlerMapper
}
}
<ApplePhone.java>
package test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component("apple")
public class ApplePhone implements Phone {
@Autowired // 메모리의 자료형(타입)을 인지해서 주입해줌
@Qualifier("aw")
private Watch watch; // 멤버변수 초기화 = 생성자 // 워치에 의존성 주입을 해야한다. // DI 대상
// private int num;
public ApplePhone() {
// this.watch = new AppleWatch(); // 개발자가 new를 직접 사용하기 때문에 사용x
System.out.println("아이폰 객체 생성 01");
}
/*
public IPhone(Watch watch) {
this.watch = watch;
System.out.println("아이폰 객체 생성 02");
}
public IPhone(Watch watch, int num) {
this.watch = watch;
this.num = num;
System.out.println("아이폰 객체 생성 03");
}
*/
// init-method="initMethod"를 bean에 추가
@Override
public void powerOn() { // 아이폰은 워치에 대해 의존성을 갖는다.
this.watch.powerOn();
System.out.println("아이폰 전원 ON");
}
@Override
public void powerOff() {
this.watch.powerOff();
System.out.println("아이폰 전원 OFF");
}
// getter,setter는 코드 하단에 기입하는것이 일반적
public Watch getWatch() {
return watch;
}
public void setWatch(Watch watch) {
this.watch = watch;
}
}
<AppleWatch.java>
package test;
public class AppleWatch implements Watch {
public AppleWatch() {
System.out.println("애플워치 생성자 호출");
}
@Override
public void powerOn() {
System.out.println("애플워치로 폰 전원 ON");
}
@Override
public void powerOff() {
System.out.println("애플워치로 폰 전원 OFF");
}
}
2024.10.04
'Spring' 카테고리의 다른 글
| [Spring] 07-1. 어노테이션의 종류(@RequestMapping,@Controller) (0) | 2024.10.10 |
|---|---|
| [Spring] 06. ModelAndView의 정의 (1) | 2024.10.08 |
| [Spring] 04. 의존성 주입 (0) | 2024.10.02 |
| [Spring] 03. Spring 컨테이너의 활용 (3) | 2024.10.01 |
| [Spring] 02. Spring 프레임워크 구조 (2) | 2024.10.01 |