🍃 Spring

Command 객체 생성 방식으로 DAO를 new하면 안 좋은 이유

보배 진 2026. 1. 19. 10:16

Command 객체로 DAO를 받으면 안 되는 이유

1. DAO가 여러개 new 됨

2. AOP 설정할 때 불편함

 

 

✅ 해결 방법: DAO를 직접 쓰지 말고 Service를 멤버 변수로 둔다

package com.example.controller.member;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.example.biz.member.MemberDTO;
import com.example.biz.member.MemberService;

import jakarta.servlet.http.HttpSession;

@Controller
public class LogoutController {
	
	@Autowired
	private MemberService memberService;
	
	@RequestMapping(value="/index", method=RequestMethod.GET)
	public String test(MemberDTO memberDTO, HttpSession session) {
		memberDTO = memberService.getMember(memberDTO);
		
		if(memberDTO == null) {
			// 로그인 실패
		} else {
			// 로그인 성공
		}
		return "어디로 갈지"; // 객체를 반환하다가 String을 반환하게 됨 = 경량화
	}
}

 

 

이전에는 DAO가 들어났다

memberService로 정의를 하면 안에 memberDAO가 있기 때문에 

눈으로는 안보여도 실질적으로는 DAO를 사용하는 것이다

 


 

멤버변수 선언방식은 AOP에 좋다

멤버변수를 사용하면 DI를 해줘야 한다

 

그래서 멤버변수를 만들었으면 생성자를 만들어 생성자 주입을 해줘야 하는데

부트 방식이기 때문에 @Autowired로 DI를 해줘야 한다

그리고 DI를 해줄 객체를 new 했어야 한다

그래서 MemberServiceImpl를 찾아가서 보면

 

 

MemberServiceImpl 코드 일부

package com.example.biz.member.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.biz.member.MemberDTO;
import com.example.biz.member.MemberService;

@Service("ms")
public class MemberServiceImpl implements MemberService {
	@Autowired
	private MemberDAO memberDAO;
	
	@Override
	public boolean insertMember(MemberDTO dto) {
		return memberDAO.insertMember(dto);
	}

	@Override
	public boolean updateMember(MemberDTO dto) {
		return memberDAO.updateMember(dto);
	}

	[ 생략 ]
}

@Service("ms") 이렇게 잘 되어 있다

 

 


 

 

package com.example.controller.member;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.example.biz.member.MemberDTO;
import com.example.biz.member.MemberService;

import org.springframework.ui.Model;
import jakarta.servlet.http.HttpSession;

@Controller
public class LogoutController {
	
	@Autowired
	private MemberService memberService;
	// DI
	// DI 해줄 객체를 new 했어야 함 -> @Service
	
	@RequestMapping(value="/index", method=RequestMethod.GET)
	public String test(MemberDTO memberDTO, Model model, HttpSession session) {
		
		memberDTO = memberService.getMember(memberDTO);
		
		session.invalidate();
		
		if(memberDTO == null) {
			// 로그인 실패
		} 
		else {
			// 로그인 성공
			model.addAttribute("user", memberDTO);
			model.addAttribute("userNmae", memberDTO.getMname());
		}
		return "main"; // 객체를 반환하다가 String을 반환하게 됨 = 경량화
		// VR
		// /WEB-INF/views/ + main + .jsp
		// /WEB-INF/views/main.jsp
	}
}

뭐 보내줘~~~ model이 인자로 추가된다

 

 

 

 

Model이 Controller 메서드 인자로 추가될 수 있는 이유

Spring MVC / Spring Boot에서는 Controller 메서드의 인자를 개발자가 직접 new 하지 않아도 된다

public String test(MemberDTO memberDTO, Model model, HttpSession session)

이게 가능한 이유는 DispatcherServlet이 메서드 인자를 자동으로 준비해주기 때문이다

 

 

 

Model은 Command 객체가 아니다

구분 역할
Command 객체 사용자 요청 파라미터 바인딩 (DTO)
Model View(JSP)에 전달할 데이터 저장소
HttpSession 세션 관리 객체

model은 요청 데이터를 받는 객체가 아니라,

View로 데이터를 보내는 객체다

 

 

Model은 누가 만들까?

개발자가 new Model() X

Spring MVC 내부에서 자동 생성 O

 

[ 내부 흐름 ]

요청 발생
 ↓
DispatcherServlet
 ↓
HandlerAdapter
 ↓
Controller 메서드 호출
   ↳ 이때 Model 객체를 만들어서 인자로 주입

그래서 Controller 메서드에 Model model을 그냥 적기만 해도 사용할 수 있다

 

 

 

 

Model을 인자로 받으면 뭐가 좋은가?

1. View에 전달할 데이터가 명확

2. request / response 의존 제거

3. 테스트 쉬움

4. Controller 책임 분리

 

 


Spring MVC에서는 Controller 메서드의 인자로
Command 객체, Model, HttpSession과 같은 객체를
직접 생성하지 않아도 사용할 수 있다.
이는 DispatcherServlet과 HandlerAdapter가
요청 시점에 필요한 객체를 자동으로 준비해 주기 때문이다.
그 결과 Controller는 요청 처리와 흐름 제어에만 집중할 수 있다.