열심히 끝까지

디바이스 융합 자바(Java) day65(1) - 스프링(생성자 인젝션(day64(2)참고), Setter 인젝션) 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)

디바이스 융합 자바(Java) day65(1) - 스프링(생성자 인젝션(day64(2)참고), Setter 인젝션)

노유림 2022. 9. 14. 11:56

[어제 나온 질문의 답변]
- new를 코드에 작성하면,
          설정변화에 따라
          코드가 변경될 수 밖에 없음!
            >> 결합도가 높다!!!


스프링 프레임워크
"IoC와 AOP 지원하는 경량의 프레임워크"
제어의 역행 IoC
    : new를 내가 안하는 것
    : 컨테이너가 하는 것
    <bean> == new

스프링 설정 파일 보여주세요!
   == applicationContext 보여주세요!

  객체가 멤버로 객체를 갖는다?
    == 의존관계가 생김
    == 의존성을 주입시켜주어야 함(=의존성 주입(DI))
            - 생성자 인젝션(galaxy, iphone 워치 및 폰 생성(day64(2) 참고)
            - Setter 인젝션 

  >> 객체화를 하고 싶다..
         - 멤버변수가 2개 있음
         - 멤버 변수를 초기화하는 방법
             1. 기본생성자 + setter
             2. 생성자

 

>> Setter 인젝션
1. <bean id="phone">
2. <bean id="aw">
3. <bean id="phone">의 <property> 진행

 

>> Setter 인젝션으로 변경하기[디바이스 융합 과제 9/13 참고] - 변경된 부분만 작성

 

------------IPhone.java

package test;

public class IPhone implements Phone{
	
	private Watch watch;
	// 애플워치로 소리를 업,다운 한다고 가정
	
	private int battery;
	
	public IPhone() {
		System.out.println("아이폰 객체생성완료");
	}
	public Watch getWatch() {
		return watch;
	}
	public void setWatch(Watch watch) {
		System.out.println("아이폰setter호출 됨-watch");
		this.watch=watch;
	}
	public int getBattery() {
		return battery;
	}
	public void setBattery(int battery) {
		System.out.println("아이폰setter호출 됨-battery");
		this.battery=battery;
	}
	
	// DI : 생성자 인젝션
	/*
	public IPhone(Watch watch) {
		// 미리 선언해주면 객체화 안해줘도 괜찮음
		System.out.println("아이폰 객체 생성완료22");
		this.watch=watch;
	}
	public IPhone(Watch watch, int battery) {
		System.out.println("아이폰 객체 생성완료333");
		this.battery=battery;
		System.out.println("아이폰 전원 On : " + battery);
		this.watch=watch;
	}
	*/
	public void powerOn() {
		System.out.println("아이폰 전원 ON");
	}
	public void powerOff() {
		System.out.println("아이폰 전원 OFF");
	}
	
	public void volumeUp() {
		// System.out.println("아이폰 소리++");
		// watch = new AppleWatch();
		// 객체화를 할 수 밖에 없음
		// 이 것을 IoC 지원을 받아 처리해보기
		watch.volumeUp();
	}
	public void volumeDown() {
		// System.out.println("아이폰 소리--");
		// watch = new AppleWatch();
		// 객체화를 할 수 밖에 없음
		watch.volumeDown();
	}
}

 

------------Galaxy.java

package test;

public class Galaxy implements Phone{
	/*
	public void initMethod() {
		System.out.println("객체를 초기화하는 작업을 처리하는 메서드...");
		// bean할 때 불러오는 것 가능
	}
	public void destroyMethod() {
		System.out.println("객체 메모리를 해제할 때 호출하는 메서드...");
		// bean할 때 불러오는 것 가능
	}
	*/
	private Watch watch;
	private int battery;
	
	public Galaxy(){
		System.out.println("갤럭시 객체 On");
	}
	public Watch getWatch() {
		return watch;
	}
	public void setWatch(Watch watch) {
		System.out.println("갤럭시setter호출 됨-watch");
		this.watch=watch;
	}
	public int getBattery() {
		return battery;
	}
	public void setBattery(int battery) {
		System.out.println("갤럭시setter호출 됨-battery");
		this.battery=battery;
	}
	/*
	public Galaxy(Watch watch, int battery) {
		System.out.println("갤럭시 객체 + 배터리 생성");
		this.battery=battery;
		System.out.println("갤럭시 전원 On : " + battery);
		this.watch = watch;
	}
	*/
	// @Override 진행된 것
	public void powerOn() {
		System.out.println("갤럭시 전원 ON");
	}
	public void powerOff() {
		System.out.println("갤럭시 전원 OFF");
	}
	public void volumeUp() {
		// System.out.println("갤럭시 소리++");
		watch.volumeUp();
	}
	public void volumeDown() {
		// System.out.println("갤럭시 소리--");
		watch.volumeDown();
	}
}

 

------------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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- 아이폰일 경우 --> 
	<bean id="ip" class="test.IPhone">
		<property name="watch" ref="aw"/>
		<property name="battery" value="90"/>
	</bean>
    
	<!-- 갤럭시일 경우 -->
	<bean id="gp" class="test.Galaxy">
		<property name="watch" ref="gw"/>
		<property name="battery" value="80"/>
	</bean>

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

</beans>

 

------------Client.java

package test;

import java.util.List;
import java.util.Map;
import java.util.Set;

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

public class Client {
	public static void main(String[] args) {
		// Spring 컨테이너를 동작시킬 수 있도록 코드 작성
		AbstractApplicationContext factory=new GenericXmlApplicationContext("applicationContext.xml");
		
		// Spring 컨테이너야, 나 폰 객체가 필요해(아이폰 객체 가지고 싶어..)!
		// 형변환 필요 == Lookup == 객체요청 : 컨테이너야, 가지고 있는 객체중에서 이름이 "phone"인 객체를 줘!
		Phone phone=(Phone)factory.getBean("phone");
		
		phone.powerOn();
		phone.volumeUp();
		phone.volumeDown();
		phone.powerOff();

		factory.close();
	}
}

 

 

>> 우선 시키는 것
   - 오래된 문법, 예전 회사의 프로젝트를 분석
   - 나은 방향을 제시 및 유지보수
  > 이때 사용되는 것?
       - 프레임워크 --->> Boot
       - xml --->> @

>> 많이 나오진 않지만 자주 나오는(보는) 문법
   [ p 네임스페이스 ]
     : 이름 덩어리
        ex ) 1반 김은지 | 김지은 | 김지연
              2반 김은지 | 김지은 | 김지연
          >> 지은아~ 라고 했을 때, 
                컴퓨터에서는 너무 많아서 누굴 선택할 지 모르겠습니다 라고 호출
             > 네임스페이스 1반 이라고 지정하면?
                : 컴퓨터에서는 1반의 김지은을 호출 
         >>> 지금부터 내가 A 네임 스페이스를 쓸거야! 라고 하면
                A가 우선 호출되는 것
            >> 겹치는 것들에 한해서 우선 적용

   p 네임 스페이스 == 도구에 불가 Namespaces에서 p선택하여 사용 가능하지만
   [ xmlns:p="http://www.springframework.org/schema/p" ] 를 직접 써서 사용하는 것도 가능

   p:멤버변수명-ref = "주입할 객체명"
   p:멤버변수명 = "주입할 값"

 

위의 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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- 
	<bean id="ip" class="test.IPhone">
		<property name="watch" ref="aw"/>
		<property name="battery" value="90"/>
	</bean>
	 -->
	 <!-- 위 항목을 아래처럼 작성 가능[p 네임스페이스 사용 시] -->
	<bean id="ip" class="test.IPhone" p:watch-ref="aw" p:battery="90"/>
	
	 <!-- 
	<bean id="gp" class="test.Galaxy">
		<property name="watch" ref="gw"/>
		<property name="battery" value="80"/>
	</bean>
	 -->
    <!-- 위 항목을 아래처럼 작성 가능[p 네임스페이스 사용 시] -->
	<bean id="gp" class="test.Galaxy" p:watch-ref="gw" p:battery="80"/>
    
	<bean id="aw" class="test.AppleWatch"/>
	<bean id="gw" class="test.GalaxyWatch"/>

</beans>

 

 


List, Set, Map도 사용 가능한가???

>> 충분히 가능하다!!!!

 

--------------------TestBean.java

package test;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class TestBean {
	
	// 리스트(List)
	private List<String> datas;
	// ex ) 댓글, 대댓글

	public List<String> getDatas() {
		return datas;
	}

	public void setDatas(List<String> datas) {
		this.datas = datas;
	}
	
	// 셋(Set)
	private Set<String> datas2;

	public Set<String> getDatas2() {
		return datas2;
	}

	public void setDatas2(Set<String> datas2) {
		this.datas2 = datas2;
	}
	
	// 맵(Map)
	private Map<String,String> datas3;

	public Map<String,String> getDatas3() {
		return datas3;
	}

	public void setDatas3(Map<String,String> datas3) {
		this.datas3 = datas3;
	}
	
}

 

--------------------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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean id="tb" class="test.TestBean">
		<!-- 기본생성자는 작성하지 않으면 원래 있다 -->
		<!-- datas = list 예시 --> 
		<property name="datas">
			<list>
				<value>서울시</value>
				<value>서울시 관악구</value>
				<value>사당역</value>
			</list> 
		</property>
		<!-- datas2 = set -->
		<property name="datas2">
			<set>
				<value>바나나</value>
				<value>키위</value>
				<value>사과</value>
			</set>
		</property>
		<!-- datas3 = map -->
		<property name="datas3">
			<map>
				<entry>
					<key><value>아무무</value></key>
					<value>서포터</value>
				</entry>
				<entry>
					<key><value>티모</value></key>
					<value>탑</value>
				</entry>
				<entry>
					<key><value>아리</value></key>
					<value>미드</value>
				</entry>
			</map>
		</property>
	</bean>

</beans>

 

--------------------Client.java

package test;

import java.util.List;
import java.util.Map;
import java.util.Set;

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

public class Client {
	public static void main(String[] args) {
		// Spring 컨테이너를 동작시킬 수 있도록 코드 작성
		AbstractApplicationContext factory=new GenericXmlApplicationContext("applicationContext.xml");
		
		TestBean tb=(TestBean)factory.getBean("tb");
        
		List<String> datas=tb.getDatas();
		Set<String> datas2=tb.getDatas2();
		Map<String,String> datas3 = tb.getDatas3();
		
        // 출력
		// 축약된 형태
		for(String v:datas) { // 축약된 형태(위의 List 언급 안해도 됨)- String v:tb.getDatas()
			System.out.println(v);
		}
        for(String v:datas2) { // 축약된 형태(위의 Set 언급 안해도 됨)- String v:tb.getDatas2()
			System.out.println(v);
		}
		System.out.println(datas3);
		
		factory.close();
	}
}