스프링의 주요 특징
1. POJO (Plain Old Object) 기반의 구성
- 객체간의 관계를 구성 할 때, 별도의 API 등을 사용하지 않는 POJO의 구성만으로 가능
- 코드를 개발할 때 개발자가 특정한 라이브러리나 컨테이너 기술에 종속적이지 않는 것을 뜻함
2. 의존성 주입(DI: Dependency injection)과 스프링
- 의존성이라는 것은 하나의 객체가 다른 객체 없이 제대로 된 역할을 할 수 없음을 의미
- 주입은 외부에서 밀어 넣는것
- 의존성 주입은 객체 자체가 아니라 Framework에 의해 객체의 의존성이 주입되는 설계 패턴
1) 객체의 의존성
어떤 객체가 다른 객체에 의존하는 관계
public class PetOwner{ //PetOwner 클래스 선언
private AnimalType animal; //AnimalType의 클래스자료형의 멤버변수 animal선언
public PetOwner() { //PetOwner 클래스의 생성자 정의
this.animal = new Dog(); // Dog클래스를 현재객체의 animal변수에 할당
}
}
* 생성자의 이름은 클래스 이름과 같고, 리턴값이 없다. 주로 인스턴스 변수의 초기화 작업에 사용된다.
* this 는 java에서 현재 객체를 가리킬 때 사용한다.
public class MyClass {
private int myVariable;
public void setMyVariable(int myVariable) {
this.myVariable = myVariable; // 멤버 변수와 매개변수 이름이 같을 때 this를 사용하여 구분
}
}
PetOwner클래스가 Dog클래스에 의존한다.
= PetOwner클래스가 직접 Dog클래스의 인스턴스를 생성하고 사용한다.
= 두 클래스가 긴밀한 결합(Tight Coupling)이 되어 있다.(하나의 클래스를 수정하면, 다른 하나도 영향을 받을 수 있다.)
= 유지보수가 어려워진다.
= 단위 테스트가 어려워진다. Dog 클래스를 테스트 할 때 PetOwner클래스도 함께 테스트를 해야한다.
2) 의존성 주입
- 클래스가 필요로 하는 의존 객체를 직접 생성하는 것이 아니라 외부(Framework)에서 주입받아 사용하는 패턴
- IoC는 의존성 주입패턴을 사용하여 객체 간의 관계를 구성하고, 객체를 생성하며, 응용 프로그램 코드는 이러한 컨테이너를 사용하여 객체를 얻고 필요한 작업을 수행한다.
- Java에서 Spring Framework는 IoC를 구현한 프레임 워크로, 의존성 주입을 통해 객체 간의 관계를 설정하고 컨테이너에서 필요한 객체를 검색할 수 있다,
* 제어의 역전(Inversion of Control, IoC)은 소프트웨어 개발 패턴 중 하나로 응용 프로그램의 제어 흐름을 개발자가 직접하는 것이 아니라 프레임워크 또는 컨테이너에 의해 제어되는 패턴을 의미한다.
* IoC의 주요 목표는 코드의 결합도를 낮추고 코드 재사용성, 유지보수성, 테스트 가능성을 향상시키는 것이다.
import org.springframework.context.ApplicationContext;
// ApplicationContext는 객체생성 및 의존성 주입을 담당.
// 관리하는 객체를 bean이라 하고,
// 빈과 빈사이의 의존관계를 처리하는 방식으로 XML형식의 설정파일, 어노테이션 설정, JAVA설정 방식을 이용 할 수 있음
import org.springframework.context.support.ClassPathXmlApplicationContext;
// ApplicationContext를 생성
// XML형식의 설정파일 로드
// 클래스 내부에서 XML설정 파일에 정의 된 스프링 빈들을 인스턴스화 하고, 필요한 의존성을 주입
// 생성된 ApplicationContext 객체를 반환
public class MyApplication {
public static void main(String[] args) {
// Spring IoC 컨테이너를 XML설정 파일을 매개변수로 받아 통해 생성
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// IoC 컨테이너에서 필요한 객체를 얻음
UserService userService = (UserService) context.getBean("userService");
// 객체 사용
userService.doSomething();
}
}
public class UserService {
private UserRepository userRepository;
// 의존성 주입을 통해 UserRepository 객체를 주입
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void doSomething() {
// UserRepository 객체 사용
userRepository.saveUser();
}
}
public class UserRepository {
public void saveUser() {
System.out.println("User saved.");
}
}
*ClassPathXmlApplicationContext, ApplicationContext
spring-config.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">
<!-- UserService 빈 정의 -->
<bean id="userService" class="com.example.UserService">
<!-- userService 빈의 의존성(UserRepository) 주입 -->
<property name="userRepository" ref="userRepository" />
<!-- doSomething 메서드 호출 -->
<lookup-method name="doSomething" bean="anotherBean" />
</bean>
<!-- UserRepository 빈 정의 -->
<bean id="userRepository" class="com.example.UserRepository" />
</beans>
출처
https://gmlwjd9405.github.io/2018/11/09/dependency-injection.html