[Spring] DI(의존성주입)3

김장환·2022년 8월 22일

Spring

목록 보기
5/17

저번에 이어서 DI(의존선주입)을 예제를 통해 정리하고자 한다.

byType

  • 속성의 타입과 같은 타입을 갖는 빈객체를 생성
  • byType은 @Autowired와 같다.
  • 멤버변수의 자료형과 똑같은 자료형의 객체를 찾아서 넣을때 사용

1.PhoneCall.java생성

package spring10;

public class PhoneCall {}

2. SystemMoniter.java 생성

package spring10;

public class SystemMoniter {
	//1)byType =>@Autowired와 같음 => 속성의 타입과 같은 타입을 갖는 빈객체를 생성
	
	private PhoneCall call;//PhoneCall과 같은 자료형의 객체를 찾아와 멤버변수 call에 자동으로 저장
	
	public void setCall(PhoneCall call) { // <property name="call">
		this.call = call;
		System.out.println("setCall() call=>"+call);
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "[PhoneCall object]=>"+phonecall;
	}
}


3. Main.java 생성

  • xml경로 app.xml로 변경한다 (이따가 app.xml을 새로 만들기 때문)
  • 이전꺼에서 id값과 형변환 할 클래스를 수정한다.

package spring10;

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

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//1.메모리관리->xml파일이 여러개->배열로 관리->파일명부여  // xml이 여러개면 ,로 쭉쭉 나열 가능
			String [] configLocation=new String[] {"app.xml"};	
		//2.xml파일을 메모리에 올려줄 수 있는 클래스를 통해서 객체를 생성
			AbstractApplicationContext context=
					new ClassPathXmlApplicationContext(configLocation);
		//3.자바프로그램이 종료->자동적으로 context객체도 같이 종료 설정	
			context.registerShutdownHook();
		//4.xml에서 만들어진 객체를 가져와서 처리	
		
			//형식) ~getBean("의존성객체를 얻어올id",형변환을 할 클래스명.class)
			SystemMoniter moniter=
					context.getBean("systemMoniter",SystemMoniter.class);
			System.out.println("moniter=>"+moniter);
			
		//5.context도 종료
			context.close();//메모리에 올려놓은 모든 빈즈객체->메모리해제
	}

}

4. app.xml 생성

byType:멤버변수의 자료형과 똑같은 자료형의 객체를 찾아서 넣을때 사용

  • 기존에 사용하던 전역 xml은 복잡해져서 새로 만들었다.
  • @Autowired이렇게 써도된다.(요즘은 이걸로 씀)
  • autowire="byType"을 빈에 추가하여 사용한다.
  • byType이면 class가 중요하다
  • 같은 자료형의 빈즈객체가 한개이상이 존재하면 에러유발힌다
    => 하나만 설정해야되는데 두개를 설정하면 어느것을 넣어줄지 구분할 수가 없기때문에
<bean id="systemMoniter" class="spring10.SystemMoniter">
	<property name="call">
		<ref bean="phoneCall" />
	</property>
</bean>

<bean name="phonecall" class="spring10.PhoneCall" />

이거를 byType을 사용하면?

<bean id="systemMoniter" 
	  class="spring10.SystemMoniter" 
	  autowire="byType">
</bean>

<bean name="phonecall" class="spring10.PhoneCall" />
이렇게 간단히 바꿔서 사용할 수 있다.

byName

  • 위의 byType처럼 Type으로 객체를 찾아서 넣어주는 것이 아니라 이름으로 찾아서 자동으로 객체를 넣어주는 개념
  • @Resource와 같은 개념

1. PhoneCall.java생성

  • 위에꺼랑 변함이 없기에 그대로 가져온다.
package spring10;

public class PhoneCall {}

2. SystemMoniter 수정

  • 위의 byType부분을 byName에 맞게 수정

package spring10;

public class SystemMoniter {
	
	//2)byName=>@Resource와 같은 개념=>Type으로 객체를 찾아서 넣어주는 것이 아니라
	//														   이름으로 찾아서 자동으로 객체를 넣어주는 개념
	private PhoneCall phonecall;//type가 이름을 같게 설정
								//보통 디폴트로 멤버변수이름을 객체명
	
	public void setPhonecall(PhoneCall phonecall) {
		this.phonecall = phonecall;
		System.out.println("setPhonecall call(phone)=>"+phonecall);
	}


	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "[PhoneCall object]=>"+phonecall;
	}
}


3. app.xml수정
byName: Type으로 객체를 찾아서 넣어주는 것이 아니라
이름으로 찾아서 자동으로 객체를 넣어주는 개념이다.

  • byName은 이름으로 찾는 방법
  • byName에서는 PhoneCall객체를 얻어오기위해서 멤버변수명과 name이름이 반드시 같아야 된다.
    => (대소문자구분)
  • byType이면 class가 중요 byName이면 이름이 중요
<bean id="systemMoniter" 
		   class="spring10.SystemMoniter" 
		   autowire="byName">
</bean>

<bean name="phonecall" class="spring10.PhoneCall" />
<!-- byType이면 class가 중요 byName이면 이름이 중요 -->   

4. Main 생성

  • 이전꺼랑 변함이 없기에 그대로 가져와서 실행한다.

package spring10;

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

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//1.메모리관리->xml파일이 여러개->배열로 관리->파일명부여  // xml이 여러개면 ,로 쭉쭉 나열 가능
			String [] configLocation=new String[] {"app.xml"};	
		//2.xml파일을 메모리에 올려줄 수 있는 클래스를 통해서 객체를 생성
			AbstractApplicationContext context=
					new ClassPathXmlApplicationContext(configLocation);
		//3.자바프로그램이 종료->자동적으로 context객체도 같이 종료 설정	
			context.registerShutdownHook();
		//4.xml에서 만들어진 객체를 가져와서 처리	
		
			//형식) ~getBean("의존성객체를 얻어올id",형변환을 할 클래스명.class)
			SystemMoniter moniter=
					context.getBean("systemMoniter",SystemMoniter.class);
			System.out.println("moniter=>"+moniter);
			
		//5.context도 종료
			context.close();//메모리에 올려놓은 모든 빈즈객체->메모리해제
	}

}

추상클래스와 부모자식 클래스

abstract 와 parent

  • 자바에서 객체를 생성하지 않을꺼면 추상클래스로 만들면된다.
  • 이럴때 spring에서 사용하는 방법은 abstract이다.
  • 추상클래스를 만들고 그 추상클래스를 상속받는 자식클래스를 만들려면 parent를 사용한다.

먼저 추상클래스를 먼저 정리한 후 이어서 상속으로 자식클래스를 정리하고자 한다.

abstract

  • 추상클래스는 객체 호출 불가하다.
  • abstract=true(추상클래스)를 사용하여 추상클래스를 만들어보고자 한다.

1. SmsSender.java 생성

package spring11;

//문자전송 시스템
public class SmsSender {}

2. SystemMoniter.java 생성

  • Setter Method 사용
  • has a 관계
package spring11;

//문자를 전송=>기간을 정하기
public class SystemMoniter {

	private long periodTime;//기간
	//has a 관계 =>두 클래스가 연결
	private SmsSender sender;
	//Setter Method
	public void setPeriodTime(long periodTime) {
		this.periodTime = periodTime;
		System.out.println("setPeriodTime() call");
	}
	public void setSender(SmsSender sender) {
		this.sender = sender;
		System.out.println("setSender() call=>"+sender);
	}
	
	@Override
	public String toString() {// Setter메서드로 잘 설정됐는지 확인할수있음
		// TODO Auto-generated method stub
		return "SystemMoniter[periodTime="+periodTime+",sender="+sender+"]";
	}
}

3. app.xml 내용추가

-bean에 abstract=true(추상클래스)를 사용하여 추상클래스로 만든다.


<bean id="commonMoniter" class="spring11.SystemMoniter" abstract="true">
	<property name="periodTime" value="10" />
	<property name="sender" ref="smsSender" />
</bean> 

<bean id="smsSender" class="spring11.SmsSender" />

만약 여기서 만든 추상클래스를 상속받는 자식클래스를 설정하려면?
=>parent를 사용한다.

parent

bean>태그를 써서 클래스를 등록하는 목적은 객체를 미리 생성할 목적도 있지만 상속을 이용하기 위한(자식클래스의 객체생성) 목적도 있다.

1. app.xml에 내용추가

  • 위의 추상클래스를 상속받는 자식클래스를 만들고자 한다.
  • 부모와 다르게 내용을 변경하려면 상속받고 바꿀내용만 다시 작성한다.
    => 매서드 오버라이딩

1) 부모의 멤버변수를 그대로 사용하고 싶다.(부모의 100% 그대로 사용)

<bean id="commonMoniter" class="spring11.SystemMoniter" abstract="true">
	<property name="periodTime" value="10" />
	<property name="sender" ref="smsSender" />
</bean> 

<!-- 1.부모의 멤버변수를 그대로 사용하고 싶다.(부모의 100% 그대로 사용) -->

<bean id="doorMoniter" parent="commonMoniter" />

<!-- 2.periodTime=30(부모와 다르게 내용을 변경)(매서드 오버라이딩) --> <!-- 상속받고 바꿀내용만 다시 작성 -->
<bean id="lobbyMoniter" parent="commonMoniter">
	<property name="periodTime" value="30" />
</bean>

<!-- 3.periodTime=40(부모와 다르게 내용을 변경)(매서드 오버라이딩) -->
<bean id="roomMoniter" parent="commonMoniter">
	<property name="periodTime" value="40" />
</bean>

<bean id="smsSender" class="spring11.SmsSender" />

2. Main.java 수정

  • 자식클래스들로 바꾸고 추가한다.
package spring11;

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

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//1.메모리관리->xml파일이 여러개->배열로 관리->파일명부여  // xml이 여러개면 ,로 쭉쭉 나열 가능
			String [] configLocation=new String[] {"app.xml"};	
		//2.xml파일을 메모리에 올려줄 수 있는 클래스를 통해서 객체를 생성
			AbstractApplicationContext context=
					new ClassPathXmlApplicationContext(configLocation);
		//3.자바프로그램이 종료->자동적으로 context객체도 같이 종료 설정	
			context.registerShutdownHook();
		//4.xml에서 만들어진 객체를 가져와서 처리	
		
			//형식) ~getBean("의존성객체를 얻어올id",형변환을 할 클래스명.class)
			SystemMoniter moniter=
					context.getBean("doorMoniter",SystemMoniter.class);
			System.out.println("moniter=>"+moniter);//10
			
			SystemMoniter moniter2=
					context.getBean("lobbyMoniter",SystemMoniter.class);
			System.out.println("moniter=>"+moniter2);//30
			
			SystemMoniter moniter3=
					context.getBean("roomMoniter",SystemMoniter.class);
			System.out.println("moniter=>"+moniter3);//40
			
		//5.context도 종료
			context.close();//메모리에 올려놓은 모든 빈즈객체->메모리해제
	}

}



어노테이션 @Inject

  • @Inject= 자동적으로 의존객체(has a 관계)를 찾아서 넣어주는 역할을 하는 어노테이션 (신버전)
    => 구버전 = @Autowired

  • 사용 목적:
    1.환경설정을 편하게 설정 하게 해준다 즉 xml에서의 환경설정부분을 덜 사용한다.
    2.자바코드의 일부를 담당=>자바코드를 대신사용하는 역할

  • 형식) @키워드 =>어노테이션과 관련이 있는 클래스를 import해야 한다.(ctrl+shift+O)

  • 사용위치:
    1.멤버변수 위에
    2.메서드 위에->생성자 포함해서
    3.클래스 위에



1. SystemMoniter.java 생성

  • @Inject을 설정해준다
package spring12;

import javax.inject.Inject;//외부 패키지

//문자를 전송=>기간을 정하기
public class SystemMoniter {

	private long periodTime;//기간
	//has a 관계 =>두 클래스가 연결
	//@Inject
	private SmsSender sender;//byType
	//Setter Method
	public void setPeriodTime(long periodTime) {
		this.periodTime = periodTime;
		System.out.println("setPeriodTime() call");
	}
	@Inject
	public void setSender(SmsSender sender) {
		this.sender = sender;
		System.out.println("setSender() call=>"+sender);
	}
	
	@Override
	public String toString() {// Setter메서드로 잘 설정됐는지 확인할수있음
		// TODO Auto-generated method stub
		return "SystemMoniter[periodTime="+periodTime+",sender="+sender+"]";
	}
}


2. SmsSender.java 생성


package spring12;

//문자전송 시스템
public class SmsSender {}


3. app2.xml 생성

  • 어노테이션 적용
  • 어노테이션을 쓰면 Autowired를 안써도됨
  • 간단히 가능

<bean id="moniter" parent="spring12.SystemMoniter">
	<property name="periodTime" value="50" />
</bean>

<bean id="smsSender2" class="spring12.SmsSender" />


2022-08-22

0개의 댓글