Spring Bean Object 를 새로운 Object 에 복사하기
Spring Bean 객체를 새로운 객체로 Apache BeanUtils 로 복사하는 방법을 설명한다.
도메인 객체를 작성한다.
package org.syaku.ex.beanscope;
import org.apache.commons.lang3.builder.ToStringBuilder;
public class Menu {
private String name;
private int order;
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}
위 도메인 객체를 담을 리스트를 아래와 같이 작성한다. Componet 계층을 지정하였고 이제 MenuScope 는 스프링에서 사용할 수 있는 스프링 싱글톤이 되었다.
package org.syaku.ex.beanscope;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class MenuScope {
Menu menu;
List<Menu> listMenu;
public Menu getMenu() {
return menu;
}
public void setMenu(Menu menu) {
this.menu = menu;
}
public List<Menu> getListMenu() {
return listMenu;
}
public void setListMenu(List<Menu> listMenu) {
this.listMenu = listMenu;
}
}
이제부터 위 클래스를 이용하여 예제를 설명한다.
작업의 목표는 인스턴스 Menu 객체에 데이터를 삽입하고 객체를 복사하여 처음 Menu 에 값을 수정하여 두 객체가 서로 다른 데이터를 가지게 하는 것이다. 즉 두개는 서로 참조가 아닌 다른 객체여야 한다.
package org.syaku.ex.beanscope;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.util.BeanUtil;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml")
public class AppTests {
@SuppressWarnings("SpringJavaAutowiringInspection")
@Autowired MenuScope menuScope;
@Before
public void init() {
Menu menu = new Menu();
menu.setName("최석균");
menu.setOrder(1);
menuScope.setMenu(menu);
}
@Test
public void object() {
Menu menu2 = menuScope.getMenu();
menu2.setName("최석균 업데이트");
System.out.print(menuScope.getMenu().getName());
System.out.print(menu2.getName());
}
}
테스트를 실행하면 Menu 두 객체는 마지막에 수정된 값으로 변경된다. 참조 객체이니 당연한 결과이다.
이럴때 BeanUtils.copyProperties
사용하면 두개가 틀린 데이터를 각각 수정할 수 있다.
@Test
public void object() {
Menu menu = menuScope.getMenu();
Menu menu2 = new Menu();
BeanUtils.copyProperties(menu, menu2);
menu2.setName("최석균 업데이트");
System.out.print(menuScope.getMenu().getName());
System.out.print(menu2.getName());
}
BeanUtils.copyProperties 를 사용하여 객체를 복사하면 서로 다른 참조값을 가지므로 두 객체는 서로 다른 데이터를 가질 수 있게 된다.
두 객체를 병합해야할 경우 주로 사용할 수 있다.