Spring DI & IoC

Let's Just Go·2022년 6월 30일
0

Spring

목록 보기
2/26

Spring

DI(Dependency Injection) & IoC(Inversion of Control)

Container

  • Container
    • 객체 등록 및 의존성 주입

    • Setter메서드와 유사하게 property태그를 사용해 값이나 객체를 넣을 수 있음

    • 객체를 Container에 등록을 하면 쉽게 값을 가져올 수 있음

      <?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="db1" class="basic.ex02.DataBaseInfo">
      		<!-- setter 주입 값도 넣을 수 있음 -->
      		<property name="url"
      			value="jdbc:oracle:thin@localhost:1521:xw" />
      		<property name="uid" value="test" />
      		<property name="upw" value="test123" />
      		<!-- 그냥 setter를 불러와서 각 변수에 값을 넣어준다고 생각하자 -->
      	</bean>
      
      	<bean id="dao" class="basic.ex02.MemberDAO">
      		<!-- MemberDAO는 DataBaseInfo가 있어야 함으로 property 태그를 통해 작성 -->
      		<property name="dbInfo" ref="db1" />
      		<!-- property의 name은 setter메서드의 setter를 빼고 작성 -->
      	</bean>
      	<!-- setter 메서드를 사용할 때 property 태그를 사용하는 거네 -->
      
      </beans>

    • Main

      package basic.ex02;
      
      import org.springframework.context.support.GenericXmlApplicationContext;
      
      public class MainClass {
      
      	public static void main(String[] args) {
      
      		GenericXmlApplicationContext ct = 
      				new GenericXmlApplicationContext("classpath:db-config.xml");
      
      		MemberDAO dao = ct.getBean("dao", MemberDAO.class);
      		// container에 dao라는 이름으로 되어 있는 것을 가져오는데 MemberDAO 타입에 맞게 가져와라 라는 뜻 
      		// MemberDAO는 DataBaseInfo라는 객체가 없으면 실행이 되지 않는데 Container에서 의존성을 부여했기 때문에 
      		// DAO만 가져와도 실행이 되는 것을 확인할 수 있음
      		dao.showDBInfo();
      		ct.close();
      
      	}
      
      }

Bean Scope

  • SingleTon

    • Spring Container에서 생성된 Bean 객체의 경우 동일한 타입에 대해서는 기본적으로 한 개만 생성
    • getBean() 메소드로 호출될 때 동일한 객체가 반환

  • Prototype

    • SingleTon과 반대되는 개념으로 Container에 등록되어 있는 bean을 여러 개를 생성할 수 있음

    • Prototype을 사용하기 위해서는 개별 설정이 필요하고 스프링 설정 파일에서 Bean 객체를 정의할 때 scope 속성을 명시

    • 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="person" class="basic.ex03.Person" scope="prototype">
      	<!-- 객체를 하나만 사용(싱글톤)하고 싶지 않을 때 즉 여러개 사용하고 싶을 때 scope 사용  -->
      		<property name="name" value="홍길동"></property>
      		<property name="age" value="20"></property>
      		<!-- Person 객체 등록하고 값 등록 -->
      	</bean>
      
      </beans>
    • Main

      package basic.ex03;
      
      import org.springframework.context.support.GenericXmlApplicationContext;
      
      public class Main {
      
      	public static void main(String[] args) {
      
      		GenericXmlApplicationContext 
      		ct = new GenericXmlApplicationContext("classpath:prototype-config.xml");
      		Person hong = ct.getBean("person", Person.class);
      		System.out.println(hong.getAge());
      		System.out.println(hong.getName());
      
      		// 추가 객체가 필요하다고 가정 
      		Person lee = ct.getBean("person", Person.class);
      		lee.setAge(30);
      		lee.setName("이짱구");
      
      		System.out.println("hong 이름 : " + hong.getName());
      		System.out.println("hong 나이 : " + hong.getAge());
      		System.out.println("lee 이름 " + lee.getName());
      		System.out.println("lee 나이 : " + lee.getAge());
      		// 동일한 객체에서 값이 변경되고 있으므로 하나의 객체를 사용하고 있는것을 확인할 수 있음 
      
      		System.out.println("hong 주소 값 " + hong);
      		System.out.println("lee 주소 값 " + lee);
      		System.out.println("hong과 lee은 같은 객체입니까 ? " + (hong == lee));
      		// 주소값 확인을 통해서도 같은 객체인 것을 확인할 수 있음
      
      		// xml에서 scope 속성을 사용했더니 싱글톤 특성이 사라짐
      		// scope에서 prototype를 통해서 객체를 생성할 때 마다 다른 객체를 만들어줌
      	}
      }

의존객체 자동 주입

  • 의존 객체 자동 주입

    • Spring 설정 파일에서 의존 객체를 주입할 때 constructor-org 또는 property 태그로 의존 대상 객체를 명시해야 했음

    • @Autowired와 @Resource Annotation을 활용하여 특정 객체가 필요한 의존 대상 객체를 Container에서 찾아서 주입

  • @Autowired

    • 특정 객체가 필요한 의존 대상 객체를 찾아서 주입해주는 annotation
    • xml파일에 Property 태그를 작성하지 않고 등록하고자 하는 객체가 어디있는지 디렉토리만 지정
    • 의존 대상 객체에 @Autowired annotation을 사용하면 스프링에서 자동으로 객체를 주입
    • 스캔 명령을 통해 객체를 찾아서 주입하는데 먼저 타입으로 검사하고 만약 타입을 찾아내지 못하면 이름을 통해 검색
    • Method or Constructor, Field에 @Autowired annotation 적용 가능
    • 예시 코드
      <?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.3.xsd">
      	
      	<!-- 자동 스캔 명령 추가  -->
      	<context:annotation-config/>
      	
      	<bean id="paper" class="basic.ex04.Paper" />
      
      	<bean id="prt" class="basic.ex04.Printer"/>
      <!-- <property name="paper" ref="paper" />
      		name: setter 메소드 이름, ref: 위에서 작성한 Paper객체의 id -->
      	<!-- 객체만 등록 -->
      		
      </beans>
      package basic.ex04;
      
      import org.springframework.beans.factory.annotation.Autowired;
      
      public class Printer {
      	
      	@Autowired
      	private Paper paper;
          // Paper객체를 Spring에서 찾아서 Printer객체에 자동으로 주입해줌 
      	
      //	@Autowired
      //	public Printer(Paper paper) {
      //		this.paper = paper;
      //	}
      	
      //	@Autowired
      //	public void setPaper(Paper paper) {
      //		this.paper = paper;
      //	}
      	// setter를 통해 값 전달
      	// setPaper가 없으면 Printer객체는 동작을 할 수 없음(의존성)
      	// Autowired를 통해서 xml에 property를 안적어도 자동으로 스프링이 연결해줌
      
      	public void showPaperInfo() {
      		for(String info : paper.data) {
      			System.out.println(info);
      		}
      	}
      }

  • @Qualifier(”bean id”)

    • @Autowired를 사용할 때 타입이 같은 여러개의 bean이 container에 있을 때 특정 bean을 찾도록 지정해주는 Annotation
    • @Autowired와 같이 사용
  • @Resource(name = “bean id”)

    • java 8버전 이하까지만 사용
    • @Qualifier과 같은 기능이지만 필드, 메서드에만 적용 가능
    • name 속성을 통해 특정 bean의 id 지목 가능
profile
안녕하세요! 공부한 내용을 기록하는 공간입니다.

0개의 댓글