10월 17, 2023

[Spring] VO 객체 복사하는 법 - BeanUtil.copyProperty + BeanUtil의 두 가지 library

Spring으로 코드를 짤 때 꼭 알아야 하는 것은 VO와 Bean의 개념이다. Spring으로 코드를 짜는 사람이면 모를 수 없는 두 개념이지만 개념에 대해 잘 익히지 않고 무작정 코드를 짜는 Spring 개발자들도 꽤나 있을 것이라고 생각한다.


1. VO의 개념

0 Spring에서 VO란 "Value Object"의 약자이다.

0 비즈니스 로직과 관련이 없는 데이터를 담는 데 사용하는 것이 중요한 개념이다.

0 VO는 주로 데이터를 전송하거나 저장하기 위해 사용되며, 그렇기 때문에 불변의, Read-Only, immutable 한 속성을 가진다.

0 VO의 주요 목적은 데이터를 묶어서 캡슐화하는 것이고, 그래서 자바라는 언어에서 더더욱 중요하게 활용되는 개념이다.


그렇다면 Bean의 정확한 개념은 무엇일까?

2. Bean의 개념

0 가장 쉽게 표현하면 Spring이 관리하는 객체를 의미한다.

0 Spring 컨테이너에 의해 instance화 되고 Application에서 사용되는 component, service, data access object 등과 같은 구성 요소를 의미한다.


3. Spring에서 VO 객체 복사하는 방법


0 Spring의 BeanUtils Class를 사용하면 VO 객체 간 속성을 복사할 수 있다.

0 주의할 사항으로는 BeanUtils Class가 어느 라이브러리를 import하냐에 따라 source와 target의 위치가 바뀐다는 것이다.

0 먼저 Spring Framework에서 사용되는 BeanUtils Class를 살펴보자


  1. 1. org.springframework.beans.BeanUtils (Spring Framework):

Spring Framework의 BeanUtils 클래스는 주로 Spring IoC(Inversion of Control) 컨테이너와 연계되어 사용되고 위에서 설명된 개념인 Bean과도 관련이 있다. 예시를 살펴보자


import org.springframework.beans.BeanUtils; 
public class BeanUtilsInSpringFramework
public static void main(String[] args)
// Spring BeanUtils 
Source source = new Source(); 
Target target = new Target(); 
 BeanUtils.copyProperties(source, target); 
// Spring Framework의 BeanUtils를 사용하여 빈(Bean) 간 속성 복사 
 } 
}


Spring에서는 위와 같이

BeanUtils.copyProperties(source, target); 

위 형식으로 source의 원본 객체를 target의 객체로 옮긴다.


이렇게 copyProperties 한 줄만 써주면 각각의 instance마다 set~ 형식으로 하나씩 옮기지 않아도 되서 코드의 가독성도 좋아진다.


2. org.apache.commons.beanutils.BeanUtils (Apache Commons BeanUtils)

반면 SpringFramework의 BeanUtils과는 헷갈려서는 안되는 것이 Apache Commons의 BeanUtils이다.

Apache Commons BeanUtils의 BeanUtils는 일반적인 Java 객체 간 속성 복사 및 변환을 수행하지만, Spring과는 별개의 Library이다. 따라서 Spring과 무관한 환경에서도 언제든 사용할 수 있다는 것이 장점이다.

import org.apache.commons.beanutils.BeanUtils; public class ApacheCommonsBeanUtils { public static void main(String[] args) { // Apache Commons 의 BeanUtils Source source = new Source(); Target target = new Target(); try { BeanUtils.copyProperties(target, source); } catch (Exception e) { e.printStackTrace(); } } }


Apache의 BeanUtils를 사용하면

BeanUtils.copyProperties(target, source);

SpringFramework의 BeanUtils를 사용할 때와 달리 target과 source의 위치가 달라진다는 것을 명심해야 한다.


따라서 BeanUtils를 사용할 때는 import된 library를 정확히 파악하고 target와 source의 위치를 정확하게 사용하는 것이 중요하다.