코딩 개발/Spring

Spring Legacy - javaconfig 로 Dynamic Web 실행하기

호소세 2023. 7. 16. 17:43
728x90
반응형

xmlconfig로 DynamicWeb 제작하기 : https://pabeba.tistory.com/200

 

Spring MVC 이해하기 - JUnit, 웹 프로그램 실행 (Spring legacy)

저희가 이전에 배운 Model2 Architecture, Front Controller Pattern의 진화형입니다. https://pabeba.tistory.com/158 Model 2 Architecture (MVC) Model2와 Model 1 비교해보면 재밌습니다. https://pabeba.tistory.com/157 Model 1 Architecture

pabeba.tistory.com

저번 시간에 xml config 파일로 dynamic web program을 실행했다면

오늘은 java config 파일로 실행해 보도록 하겠습니다.

 

javaconfig로 Dynamic Web 실행하기

pom.xml 파일은 동일합니다.

 

web.xml 파일과 WebAppConfig.java 파일을 비교해 보겠습니다. (이전글을 켜서 같이 보면 좋습니다.)

 

<WebAppConfig.java>

public class WebAppConfig extends AbstractAnnotationConfigDispatcherServletInitializer{

	@Override
	protected Class<?>[] getRootConfigClasses() {		
		return new Class[] {RootContextConfig.class};// 프로젝트 model 영역 설정 ( dbcp , mybatis , mybatis mapper 등 ) 
	}
	@Override
	protected Class<?>[] getServletConfigClasses() {		
		return new Class[] {ServletContextConfig.class};// springmvc web 영역 설정( view 와 controller 설정 ) 
	}
	@Override
	protected String[] getServletMappings() {		
		return new String[] {"/"};// DispatcherServlet에 대한 url pattern 지정 
	}
	@Override
	protected Filter[] getServletFilters() {		// 인코딩 설정 
		CharacterEncodingFilter encodingFilter=new CharacterEncodingFilter();
		encodingFilter.setEncoding("utf-8");
		return new Filter[] {encodingFilter};
	}
}

1. Spring MVC 웹 애플리케이션의 설정을 담당하는 WebAppConfig 클래스입니다. 

이 클래스는 AbstractAnnotationConfigDispatcherServletInitializer 클래스를 상속하고 있습니다. 

AbstractAnnotationConfigDispatcherServletInitializer 클래스는 WebApplicationInitializer 인터페이스를 구현한 추상 클래스로서, Servlet 3.0+ 환경에서 web.xml 파일을 대체하는 역할을 합니다. 이 클래스를 상속하면서 메서드를 오버라이딩하여 웹 애플리케이션의 구성 요소를 설정할 수 있습니다.

 

2. getRootConfigClasses() 메소드: 프로젝트의 모델 영역 설정을 담당합니다. 

RootContextConfig는 데이터베이스 연결 풀 (DBCP), MyBatis, MyBatis 매퍼 등과 같은 프로젝트의 비즈니스 로직 관련 설정을 담당하는 클래스입니다.

 

3. getServletConfigClasses() 메소드: Spring MVC 웹 영역 설정을 담당합니다. 

ServletContextConfig 클래스를 반환하고 있습니다. ServletContextConfig는 뷰와 컨트롤러 관련 설정을 담당하는 클래스입니다.

 

4. getServletMappings() 메소드: DispatcherServlet의 URL 패턴을 지정합니다.

현재 설정에서는 모든 URL에 대해 DispatcherServlet이 동작하도록 "/" 패턴을 반환하고 있습니다.

 

5. getServletFilters() 메소드: DispatcherServlet에 등록할 필터를 설정합니다. 

현재 설정에서는 문자 인코딩 필터인 CharacterEncodingFilter를 생성하여 UTF-8 인코딩으로 설정한 후 반환하고 있습니다. 이 필터는 요청과 응답의 문자 인코딩을 UTF-8로 처리해 주는 역할을 합니다.

 

위의 설정을 이용하면 Spring MVC 웹 어플리케이션의 구성 요소와 설정이 초기화되고, DispatcherServlet이 모든 요청을 처리합니다.

 

<RootContextConfig.java>

@Configuration
@MapperScan(value = "myproject.model.mapper") // MyBatis MapperProxy 를 위한 설정 
public class RootContextConfig {
	@Bean // 메서드에서 반환하는 객체를 스프링 컨테이너에 bean으로 등록하고 관리하게 하는 어노테이션 
	public DataSource dataSource() {
		BasicDataSource dataSource=new BasicDataSource();
		dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
		dataSource.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:xe");
		dataSource.setUsername("mango");
		dataSource.setPassword("apple");
		return dataSource;
	}
	
	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{
		SqlSessionFactoryBean sessionFactory=new SqlSessionFactoryBean();
		sessionFactory.setDataSource(dataSource);		
		org.apache.ibatis.session.Configuration conf=new org.apache.ibatis.session.Configuration();
		conf.setMapUnderscoreToCamelCase(true);
		sessionFactory.setConfiguration(conf);		
		return sessionFactory.getObject();
	}  
	@Bean
	public SqlSessionTemplate sqlSession(SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}

이 설정은 이전에 많이 설명드린 dbcp, SqlSessionFactory, SqlSessionTemplate 객체를 생성하는 설정 파일입니다.

@Configuration

@MapperScan(value = "myproject.model.mapper")

위의 두개의 어노테이션 작성이 중요합니다.

1. dbcp 생성

2. spring과 mybatis framework 연동 설정

3. 반복 전인 db연동 작업을 최소화하는 sqlSessionTemplate 객체 생성

4. MyBatis Proxy 설정 (myproject.model.mapper 스캔해서 사용)

 

<ServletContextConfig.java>

@Configuration
@EnableWebMvc // 어노테이션 기반 SpringMVC 컨트롤러 설정
@ComponentScan("myproject.controller") // bean 생성 등록 관리 
public class ServletContextConfig implements WebMvcConfigurer{
	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {	
		WebMvcConfigurer.super.configureViewResolvers(registry);
		registry.jsp("/WEB-INF/views/", ".jsp");
	}
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {		
		WebMvcConfigurer.super.addResourceHandlers(registry);
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
	}
}

@Configuration

@EnableWebMvc 

@ComponentScan("myproject.controller")

1. @EnableWebMvc 어노테이션:  어노테이션 기반의 Spring MVC 컨트롤러 설정을 활성화하는 역할을 합니다.

<mvc:annotation-driven/> 설정과 동일한 역할을 수행합니다. 따라서 이 어노테이션이 적용된 클래스는 Spring MVC의 컨트롤러 관련 설정을 사용할 수 있게 됩니다.

2. @ComponentScan("myproject.controller") 어노테이션: myproject.controller 패키지 내의 컴포넌트들을 스캔하여 빈으로 등록하고 관리하도록 설정합니다. 이 설정은 XML 설정의 <context:component-scan base-package="myproject.controller" />와 동일한 역할을 수행합니다.

 

아래 메서드는 이전의 글과 동일합니다.

3. @Controller에서 선택한 뷰를 /WEB-INF/views/ 디렉터리의 JSP 리소스로 변환하여 렌더링 합니다. prefix 속성은 뷰 이름의 접두어를 설정하고, suffix 속성은 뷰 이름의 접미사를 설정합니다.

만약에 home이 반환되면 /WEB-INF/views/home.jsp 파일이 실행되는 겁니다.

 

4./resources/** 경로로 들어오는 HTTP GET 요청에 대해 정적 리소스를 처리하기 위한 설정입니다.

/resources/ 디렉터리의 정적 리소스를 효율적으로 제공합니다. (이미지나, html, css 등등... 을 저장해 놓습니다.)

 

이렇게 설정하고 이전 글에서 실행한 HomeController 메서드를 실행하면 home.jsp를 잘 불러와질 것입니다.

<HomeController.java>

@Controller
public class HomeController {
	private CustomerMapper customerMapper;
	@Autowired
	public HomeController(CustomerMapper customerMapper) {
		super();
		this.customerMapper = customerMapper;
	}
	@RequestMapping("/")
	public String home(Model model) {
		model.addAttribute("totalCustomerCount", customerMapper.getTotalCustomerCount());
		return "home"; //view name : ViewResolver 설정에 의해 WEB-INF/views/home.jsp 로 응답
	}
}

 

소감

이렇게 2가지로 항상 소개하는 이유는 우리가 어디에서 일할지 모르기 때문입니다. 어디 회사에서는 java config 파일을 사용하고 어디에서는 xml config 파일을 사용할 수도 있기 때문입니다.

여러분이 회사의 CEO 라고 생각해 보면 2가지 다 알고 있는 부하직원을 뽑으시겠습니까 아니면 1나만 알고 있는 부하직원을 뽑겠습니까. 두 개 다 하는 것은 처음에는 힘들다고 생각이 되지만 지속적으로 보다 보면 익숙해질 것이라고 생각됩니다.

아니면 선조들이 만들어 놓은 것들을 잘 불러와서 저희의 방식으로 변경하면 되기에 너무 두려워하지 않아도 된다고 생각합니다.

해보지 않은 일에 대해서 어렵다 안된다를 외치면 결국 아무것도 할 수 없는 사람이 되어버리기 때문에 모든 해보고 이야기하면 좋을 것 같습니다.

반응형