[Spring] 개념 정리 (Bean Constructor/Property, Annocation)

Use_Silver·2021년 12월 27일
0

Spring

목록 보기
4/10
post-thumbnail

Bean Constructor/Property 복습
Class - Bean 등록 방식 예제
1) XML
2) Annotation

Bean Constructor/Property 개념

  • Constructor Injection :

    • 의존 객체를 생성자를 통해 주입 (대상이 생성자)
  • Setter Injection:


Bean Constructor 예제

  • Day1시간에 구현한 TV클래스에 Speaker 클래스를 추가
  • nb 스피커, pd 스피커, enc 스피커 + interface Speaker 추가
  • Bean Property 사용해 TV클래스에 주고싶은 Speaker 할당

Speaker 추상메소드

package polymorphism;

public interface iSpeaker05 {
	// 추상메소드 선언
	// 상속관계 만들면 xml로 가져오기 편함 
	 void VolumeUp() ;
	 void VolumeDown() ;
}

nb, pd, enc speaker의 구성은 아래와 동일(iSpeaker 상속)

package polymorphism;

public class nbSpeaker05 implements iSpeaker05{

	public nbSpeaker05() {
		System.out.println("==> nbSpeaker() 시작");
	}
	public void VolumeUp() {
		System.out.println("nb Speaker 볼륨 올림");
	}
	public void VolumeDown() {
		System.out.println("nb Speaker 볼륨 내림");
	}
	
}

ssTV 생성자에서 Speaker 객체 생성

package polymorphism;

public class ssTV05 implements iTV{

	private iSpeaker05 speaker;
	
	ssTV05() { System.out.println("ssTV 호출"); }
	
	public ssTV05(iSpeaker05 speaker){
		super();
		System.out.println("ssTV05 호출");
		this.speaker = speaker;
	}

	public void PowerOn() {
		System.out.println("SS TV05 전원 켜짐");
	}

	public void PowerOff() {
		System.out.println("SS TV05 전원 꺼짐");
	}

	public void VolumeUp() {
		//System.out.println("SS TV 볼륨 높임");
		// 이미 xml에서 생성돼서 들어오므로 필요 x => 생성자 없앰
		//speaker = new pdSpeaker05();
		speaker.VolumeUp();
	}

	public void VolumeDown() {
		//System.out.println("SS TV 볼륨 낮춤");
		//speaker = new pdSpeaker05();
		speaker.VolumeDown();
	}

}

main

package polymorphism;

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

public class TVTest05 {

	public static void main(String[] args) {
          // 1. Spring 컨테이너를 구동한다. factory가 container 
          AbstractApplicationContext factory  
               = new GenericXmlApplicationContext("applicationContext05.xml");

          // 2. Spring 컨테이너로부터 필요한 객체를 요청(Lookup) 
          // == dependency lookup 
          iTV tv = (iTV) factory.getBean("tv");
          tv.PowerOn();
          tv.VolumeUp();
          tv.VolumeDown();
          tv.PowerOff();

          // 3. Spring 컨테이너를 종료한다.
          factory.close();
	}

}

applicationContext.xml

  • 의존 주입 : 의존성있는 객체 외부에서 주입
    코드 예제)
    - 의존성 있는 객체 : nb
    - 외부에서 주입 : constructor-arg
    - ssTV05 bean 객체에 nb 객체를 주입

    따라서, ssTV05는 pdSpeaker05 클래스에 의존성을 가짐

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

  <bean id="nb" class="polymorphism.nbSpeaker05" />

 	<!-- constructor injection (생성자에 전달) -->
	<bean id="tv" class="polymorphism.ssTV05" >
		<constructor-arg ref="nb"></constructor-arg>
	</bean>
	
</beans>

실행 결과

==> nbSpeaker() 시작
ssTV05 호출
SS TV05 전원 켜짐
nb Speaker 볼륨 올림
nb Speaker 볼륨 내림
SS TV05 전원 꺼짐

클래스(class) - Bean 등록

XML 방식

  • 유지보수 편함, XML 표기 부담
  • 변경될 가능성이 있을 때
  1. ssTV에서 setSpeaker method 생성
package polymorphism;

public class ssTV06 implements iTV{

	private iSpeaker05 speaker;
	
	ssTV06() { System.out.println("ssTV06 호출"); }
	
	public void setSpeaker(iSpeaker05 speaker){
		System.out.println("setSpeaker 호출");
		this.speaker = speaker;
	}

	public void PowerOn() {
		System.out.println("SS TV06 전원 켜짐");
	}

...
}

applicationContext.xml

코드 예제)
- speaker라는 이름은 ssTV06에서 선언된 변수
- property name : setter메소드 이름의 name부분 (setSpeaker -> speaker)
- property value : 변수에 맞는 값을 value를 사용해 할당
- property ref : 객체를 주입시 사용

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  
	<!-- setter method injection (참조 전달 = ref)-->
	<bean id="tv" class="polymorphism.ssTV06" >
		<property name="speaker" ref = "pd"></property>
	</bean>
	
	<bean id="pd" class="polymorphism.pdSpeaker05" />
	<bean id="enc" class="polymorphism.encSpeaker05" />
	<bean id="nb" class="polymorphism.nbSpeaker05" />
</beans>

실행 결과

ssTV06 호출
==> pdSpeaker() 시작
setSpeaker 호출
==> encSpeaker05() 시작
==> nbSpeaker() 시작
SS TV06 전원 켜짐
pd Speaker 볼륨 올림
pd Speaker 볼륨 내림
SS TV06 전원 꺼짐

예제

  1. 생성자 오버로딩 값 전달
    <bean id="bk01" class="polymorphism.Book07" />

    <!-- 기본타입을 값으로 전달해야 함 (값 전달 = value )-->
    <bean id="bk02" class="polymorphism.Book07" >
      <constructor-arg index="0" value = "Java"></constructor-arg>
      <constructor-arg index="1" value = "hong-gil-dong"></constructor-arg>
      <constructor-arg index="2" value = "31000"></constructor-arg>
    </bean> 


    <!-- setter가 있어야 작동 -->
    <bean id = "bk03" class="polymorphism.Book07">
      <property name="title" value = "스프링"></property>
      <property name="author" value = "계절"></property>
      <property name="price" value = "365000"></property>
    </bean>
public class Book07 {

	String title = "무 제";
	String author = "무 명";
	int price = 100;
	
	Book07(){
		System.out.println("==> Book06 기본 생성자");
	}
	
	Book07(String t, String a, int p){
		this.title = t;
		this.author = a;
		this.price = p;
		System.out.println("==> Book06(t,a,p) 생성자");
	}
	
	public void setPrice(int price) {
		this.price = price;
	}
...

  1. 다양한 파라미터 값 전달 예제
  • constructor-arg : 참조형과 값형 value 예제
  • method 파라미터 : p tag 전달
    <bean id="tv1" class="polymorphism.ssTV08">
      <constructor-arg index="0" ref = "pd"></constructor-arg> <!-- 참조형 -->
      <constructor-arg index="1" value = "127000"></constructor-arg> <!-- 값 형 -->
    </bean>

    <!-- 파라미터 주기 -->
    <!-- tv02.setPrice("24000"); 와 동일 -->
    <bean 	id="tv2" 
          class="polymorphism.ssTV08"
          p:speaker-ref="nb" 
          p:price="24000"/>


    <bean id="pd" class="polymorphism.pdSpeaker05" />
    <bean id="nb" class="polymorphism.pdSpeaker05" />

public class ssTV08 implements iTV{

	private iSpeaker05 speaker;
	private int price;
	
	
	ssTV08() { System.out.println("ssTV08() 호출"); }
	
	public ssTV08(iSpeaker05 speaker){
		super();
		System.out.println("ssTV08(speaker) 호출");
		this.speaker = speaker;
	}
	
	// 참조형과 값 형 동시에 생성 
	public ssTV08(iSpeaker05 speaker, int price){
		super();
		System.out.println("ssTV08(speaker) 호출");
		this.speaker = speaker;
		this.price = price;
	}
  ...

Annocation 방식

  • java 코드 수정 부담
  • 변경되지 않을 객체

annotation이란?

  • 프로그램 코드의 일부가 아닌 프로그램에 관한 데이터 제공, 코드에 정보를 추가하는 방법
  • 프로그램에게 추가 정보를 제공해주는 메타데이터(데이터를 위한 데이터)

annotation 종류

@Component : 작성한 Class Bean을 등록
@Bean : 외부 라이브러리를 bean으로 생성
@Autowired : filed, setter method, constructor에서 사용
Type에 따라서 Bean을 주입
@Inject : Autowired와 비슷한 역할
@Controller : Spring의 Controller

참고 : [Spring] Annotation 정리

예제 1) ssTV09.java

// 컨테이너에 이름 등록 
@Component("tv1")
public class ssTV09 implements iTV{

	//speaker로 container에 등록해달라 요청 => DI
	//@Autowired // 생성자, 메소드, 멤버변수로 하나씩 주입할 때 씀=> 여러개의 speaker가 존재할 때 사용 불가  (변수 하나 등록)  
	//@Resource(name="pd") // 여러개의 speaker가 존재할 때, 사용할 speaker를 지정해주면 사용 가능 (호출) = autowired+qualifier

	// 이 두개를 합친 것 == Resource
//	@Autowired  
//	@Qualifier("nb") // 두 개 이상일 때 직접 호출
	@Resource(name="nb")
	private iSpeaker05 speaker;
	private int price;
	
	ssTV09() { System.out.println("ssTV09() 호출"); }
	
	public ssTV09(iSpeaker05 speaker){
		super();
		System.out.println("ssTV08(speaker) 호출");
		this.speaker = speaker;
	}
	... 

예제 1) nbSpeaker09.java

package polymorphism;

import org.springframework.stereotype.Component;

//컨테이너에 이름 등록 
@Component("nb")
public class nbSpeaker09 implements iSpeaker05{

	public nbSpeaker09() {
		System.out.println("==> nbSpeaker09() 시작");
	}
	public void VolumeUp() {
		System.out.println("nb Speaker 볼륨 올림");
	}
	public void VolumeDown() {
		System.out.println("nb Speaker 볼륨 내림");
	}
	
}

예제 1) application09.xml

<!-- 패키지 안의 내용을 자동으로 인식  -->
<!-- 변수를 줄 수있는 부분이 없음 so, annotation에 변수 명 줌  -->
	<context:component-scan base-package="polymorphism"></context:component-scan>
profile
과정은 힘들지만😨 성장은 즐겁습니다🎵

0개의 댓글