Spring Framework의 특징(POJO, IoC, DI)

김병수·2022년 10월 12일
0
post-thumbnail

POJO(Plain Old Java Object)

plain old란 평범한, 순수한이란 뜻이다. POJO는 Java로 생산한 순수한 객체를 의미한다. POJO 프로그래밍에는 두 가지 규칙이 존재한다.

  1. Java나 Java의 스펙(사양)에 정의된 것 이외에는 다른 기술이나 규약에 얽매이지 않아야 한다.
public class MessageForm extends ActionForm{ // (1)
	
	String message;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
	
}

public class MessageAction extends Action{ // (2)
	
	public ActionForward execute(ActionMapping mapping, ActionForm form,
		HttpServletRequest request, HttpServletResponse response)
        throws Exception {
		
		MessageForm messageForm = (MessageForm) form;
		messageForm .setMessage("Hello World");
		
		return mapping.findForward("success");
	}
	
}

(1)번 코드의 ActionForm 클래스나 (2)번 코드의 Action 클래스의 상속의 경우, Struts라는 웹 프레임워크에서 지원하는 클래스이다. 특정 기술의 코드를 상속받게 되어 애플리케이션의 요구사항이 변경되면 이를 일일이 제거하거나 수정해야한다.

  1. 특정 환경에 종속적이지 않아야 한다.

POJO 프로그래밍이 필요한 이유

  • 특정 환경이나 기술에 종속적이지 않으면 재사용 가능하고, 확장 가능한 유연한 코드를 작성할 수 있다.
  • 저수준 레벨의 기술과 환경에 종속적인 코드를 애플리케이션 코드에서 제거 함으로써 코드가 깔끔해진다.
  • 코드가 깔끔해지기 때문에 디버깅하기도 상대적으로 쉽다.
  • 특정 기술이나 환경에 종속적이지 않기 때문에 테스트 역시 단순해진다.
  • 객체지향적인 설계를 제한없이 적용할 수 있다.(가장 중요한 이유)

POJO 프로그래밍을 위해서는 코드 작성시, 코드가 객체지향스러운가에 대한 고민을 하는 습관을 가지는 것이 중요하다.

IoC(Inversion of Control)

애플리케이션 흐름의 주도권이 뒤바뀐 상황(제어의 역전)
일반적인 자바 코드의 경우, main 메서드 안에서 다른 객체의 메서드를 호출하는 흐름이 일반적이다. 하지만 웹 프레임워크의 경우, 별도의 main 메서드가 없기 때문에 호출 흐름이 역전된다고 볼 수 있다.

DI(Dependency Injection)

IoC의 개념을 구체화시킨 것으로 해석할 수 있다. 직역하면 의존성 주입으로 객체지향 프로그래밍에서 객체간의 의존 관계를 느슨하게 해주는 것이다. 여기서 의존 관계란 한 클래스가 다른 클래스의 메소드를 사용하거나 호출하는 경우를 의미한다.
Client 클래스

public class Client {
	public static void main(String[] args) {
		MenuService menuService = new MenuService();
		MenuController controller = new MenuController(menuService); // 의존성 주입
		List<Menu> menuList = controller.getMenus();
	}
}

MenuController 클래스

public class MenuController {
	private MenuService = menuService;
	
	// 생성자의 파라미터를 MenuService의 객체로 입력받음
	public MenuController(MenuService menuService) { 
		this.menuService = menuService;
	}
	public List<Menu> getMenus() {
		return menuService.getMenuList();
	}
}

MenuService 클래스

public class MenuService {
	public List<Menu> getMenuList() {
		return null;
	}
}

한 클래스의 생성자의 파라미터를 객체로 입력받는 경우를 의존성 주입이라 한다.

DI가 사용되는 이유

클래스 간에는 느슨한 결합(Loose Coupling)이 필요하다. 하지만 객체를 생성할 때, new 키워드를 사용하여 생성하면 클래스들 간에 강한 결합이 된다. 해당 클래스의 이름을 변경하면 해당 코드를 전부 고쳐야 하기 때문이다. 이는 Spring이 대신하도록 설정할 수 있다.

Client 클래스

public class Client {
	public static void main(String[] args) {
		GenericApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
		MenuController controller = context.getBean(MenuController.class);
		List<Menu> menuList = controller.getMenus();
	}
}

MenuController 클래스

public class MenuController {
	private MenuService = menuService;
	
	@Autowired
	public MenuController(MenuService menuService) { 
		this.menuService = menuService;
	}
	public List<Menu> getMenus() {
		return menuService.getMenuList();
	}
}

Config

@Configuration
@ComponentScan(basePackageClasses = Client.class)
public class Config {
	@Bean
	public MenuService getMenuService() {
		return new MenuServiceStub();
	}
	@Bean
	public MenuController getMenuController(MenuService menuService) {
		return new MenuController(menuService);
	}
}

@Autowired나 @Bean같은 어노테이션을 통해 new 키워드 없이 생성자를 대신 생성할 수 있다.

profile
BE 개발자를 꿈꾸는 대학생

0개의 댓글