본문 바로가기
Java/Spring

Spring #1 : 의존성 주입, 초기 개발환경 설정 (230116)

by haheehee 2023. 1. 16.
728x90

Spring 환경설정하기

 

File - new - other - Java Project

(module은 don't create)

그리고 lib폴더를 만들어서 해당 .jar파일들을 복사-붙여넣기.

오른쪽마우스-properties로 들어간다.

복사한 jar파일들을 Add JARs해서 classpath에 추가해준다.

 


의존성

 

- 연관 관계를 개발자가 직접 코딩을 통해 컴포넌트(클래스)에 부여하는 것이 아니라,

   컨테이너가 연관 관계를 직접 규정하는 것

- 코드에서 직접적인 연관 관계가 발생하지 않으므로 각 클래스들의 변경이 자유로워진다. (loosely coupled, 약한 결합)

- 서로 관련이 있는 기능들은 강하게 결합( tightly coupled)하고,

   관련이 없는 기능들은 약하게 결합(loosely coupled)해야 좋은 프로그램

 

- Spring은 약한 결합

 

의존성 주입

- 클래스들 간의 의존 관계를 최소화하여 코드를 단순화할 수 있다.

- 애플리케이션을 쉽게 유지, 관리할 수 있다.

- 의존성 주입은 객체의 생성, 소멸과 객체 간의 의존 관계를 컨테이너가 제어한다.

   (기존 구현 방법은 개발자가 직접 코드 안에서 객체의 생성과 소멸을 제어)

 

제어의 역전(Inversion of Control)

- 스프링 프레임워크에서는 객체의 제어를 스프링이 직접 담당한다.

   (기존 코드에서는 개발자가 직접 객체를 제어)

- IoC의 종류는 여러 가지,

    일반적으로 스프링에서는 DI로 IoC의 기능을 구현 -> IoC보다는 DI라는 용어를 더 많이 사용한다.

 

스프링의 의존성 주입 방법

  1. 생성자에 의한 주입
  2. Setter에 의한 주입

 

<bean> 태그

속성 이름 description
id 빈 객체의 고유 이름, id를 이용하여 빈에 접근
name 객체의 별칭
class 생성할 클래스. 패키지 이름까지 입력해야 한다.
constructor-arg 생성자를 이용해 값을 주입할 때 사용
property setter를 이용해 값을 주입할 때 사용
lazy-init - 빈 생성을 톰캣 실행 시점이 아닌, 해당 빈 요청시 메모리에 생성할 수 있다.
- true, false, default 로 지정할 수 있다.
- 설정하지 않거나, false로 설정하면, 톰캣 실행 시 빈이 생성된다.
- true로 설정하면, 해당하는 빈 사용 시에 빈이 생성된다.

 

 


의존성 주입(setter 사용) 실습 #1

 

프로젝트의 마우스 오른쪽- new - other - XML - XML File - Next

person.xml로 이름 설정

Create file from a template한 후, Finish.

 

이 person.xml에는 객체생성하는 코드를 태그형태로 만들 것이다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	<bean id="personService" class="com.spring.ex01.PersonServiceImpl">
		<property name="name">
			<value>김자바</value>
		</property>
	</bean>
</beans>

person.xml

setter를 사용하므로, property태그를 사용

 

package 생성

1개의 인터페이스와 

2개의 클래스 생성

 

package com.spring.ex01;

public interface PersonService {
	public void sayHello();
}

PersonService.java

 

package com.spring.ex01;

public class PersonServiceImpl implements PersonService {
	private String name;
	private int age;
	
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public void sayHello() {
		System.out.println("이름 : " + name);
		System.out.println("나이 : " + age);
	}
}

PersonService.java

 

package com.spring.ex01;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class PersonTest {

	public static void main(String[] args) {
		BeanFactory factory = new XmlBeanFactory(new FileSystemResource("person.xml"));	// 실행 시 person.xml 파일을 읽어 빈을 생성
		PersonService person = (PersonService) factory.getBean("personService");
		// PersonService person = new PersonServiceImpl(); // 더이상 자바 객체 생성하지 않아도 됨.
		person.sayHello();	// 생성된 빈을 이용해 name값을 출력
	}
}

PersonTest.java

- BeanFactory factory = new XmlBeanFactory(new FileSystemResource("person.xml"));

// 실행 시 person.xml 파일을 읽어 빈을 생성

- // PersonService person = new PersonServiceImpl(); // 더이상 자바 객체 생성하지 않아도 됨.
- person.sayHello(); // 생성된 빈을 이용해 name값을 출력

 

실행결과 콘솔 창 

- name 속성 값은 person.xml에서 태그로 설정한 값이 출력되지만 age 속성 값은 0이 출력(디폴트값)

 


생성자 DI 기능 실습 #2

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	<bean id="personService1" class="com.spring.ex02.PersonServiceImpl">
		<constructor-arg value="김디비" />
	</bean>
	
	<bean id="personService2" class="com.spring.ex02.PersonServiceImpl">
		<constructor-arg value="박자바" />
		<constructor-arg value="27" />
	</bean>
</beans>

person.xml

- id가 personService1, personService2인 bean태그 2개 생성

생성자를 사용하므로, constructor-arg 태그를 사용

 

package com.spring.ex02;

public class PersonServiceImpl implements PersonService {
	private String name;
	private int age;
	
	public PersonServiceImpl(String name) {
		this.name = name;
	}
	
	public PersonServiceImpl(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	@Override
	public void sayHello() {
		System.out.println("이름 : " + name);
		System.out.println("나이 : " + age);
	}
}

PersonServiceImpl.java 생성.

여기서 setter가 아닌 생성자를 생성해준다.

 

package com.spring.ex02;

public interface PersonService {
	public void sayHello();
}

PersonService.java 생성

 

package com.spring.ex02;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class PersonTest2 {

	public static void main(String[] args) {
		BeanFactory factory = new XmlBeanFactory(new FileSystemResource("person.xml"));	// 실행 시 person.xml 파일을 읽어 빈을 생성
		
		PersonService person1 = (PersonService) factory.getBean("personService1");
		person1.sayHello();	// 생성된 빈을 이용해 name값을 출력
		System.out.println();
		
		PersonService person2 = (PersonService) factory.getBean("personService2");
		person2.sayHello();	// 생성된 빈을 이용해 name과 age값을 출력
	}
}

PersonTest2.java 생성

- id가 personService1인 빈을 가져오고,

- id가 personService2인 빈을 가져와 사용.

 

콘솔 실행창.

 


의존성 주입 : 회원 실습 #3

 

xml, 

DAO 2개,

Service 2개 

main문인, 활용클래스 memberTest.java

순서로 만들기

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	<bean id="memberService" class="com.spring.ex03.MemberServiceImpl">
		<property name="memberDAO" ref="memberDAO" />
	</bean>
	<bean id="memberDAO" class="com.spring.ex03.MemberDAOImpl" />
</beans>

member.xml

- setter사용할 것! -> property태그 사용

 

package com.spring.ex03;

public class MemberDAOImpl implements MemberDAO {
	@Override
	public void listMembers() {
		System.out.println("listMembers 메서드 호출");
		System.out.println("회원정보를 조회합니다.");
	}
}

MemberDAOImpl.java

package com.spring.ex03;

public interface MemberDAO {
	void listMembers();
}

MemberDAO.java

 

package com.spring.ex03;

public class MemberServiceImpl implements MemberService {
	private MemberDAO memberDAO;
	
	public void setMemberDAO(MemberDAO memberDAO) {
		this.memberDAO = memberDAO;
	}

	@Override
	public void listMembers() {
		memberDAO.listMembers();
	}
}

MemberServiceImpl.java

package com.spring.ex03;

public interface MemberService {
	void listMembers();
}

MemberService.java

 

package com.spring.ex03;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class MemberTest01 {
	public static void main(String[] args) {
		BeanFactory factory = new XmlBeanFactory(new FileSystemResource("member.xml"));
		MemberService service = (MemberService) factory.getBean("memberService");
		service.listMembers();
	}
}

MemberTest01.java

활용클래스

 

콘솔 실행창

 


xml 파일에서 lazy-init 실습 #3

 

false가 기본.

lazy-init을 생략하거나 default, false로 설정하면 다 같은 결과!

true로 설정해주면, 활용클래스 쪽에서 호출될 때, 빈 생성

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	<bean id="firstBean" class="com.spring.ex04.First" lazy-init="false" />
	<bean id="secondBean" class="com.spring.ex04.Second" lazy-init="true" />
	<bean id="thirdBean" class="com.spring.ex04.Third" lazy-init="default" />
</beans>

lazy.xml

lazy-init 속성값!!

 

// First.java
package com.spring.ex04;

public class First {
	public First() {
		System.out.println("First 생성자 호출");
	}
}

// Second.java
package com.spring.ex04;

public class Second {
	public Second() {
		System.out.println("Second 생성자 호출");
	}
}

// Third.java
package com.spring.ex04;

public class Third {
	public Third() {
		System.out.println("Third 생성자 호출");
	}
}

First.java

Second.java

Third.java

 

package com.spring.ex04;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class LazyTest {
	public static void main(String[] args) {
		ApplicationContext context = new FileSystemXmlApplicationContext("lazy.xml");
		System.out.println("SecondBean 얻기");
		context.getBean("secondBean");
	}
}

LazyTest.java

 

콘솔 실행창.

First와 Third 클래스는 application이 실행될 때, 빈이 생성되었다. 

Second 클래스는 context.getBean()이 호출된 후, 생성된 것!!

 

 

728x90

댓글