BE전문가 프로젝트

3. xml과 Annotaion을 이용하여 객체를 설정하는 방법(DI Demo, DIDemo2) 본문

Spring 코딩

3. xml과 Annotaion을 이용하여 객체를 설정하는 방법(DI Demo, DIDemo2)

원호보고서 2021. 11. 11. 00:35

<프로젝트 구성>

 

Printer Interface생성

package com.example;

public interface Printer {
	void print(String message);
}

void print라는 추상메소드를 생성한다. lombok에서 제공하는 Annotaion을 활용하여 setter메소드와 기본생성자를 만들거주는 @NoArgsConstructor를 이용한다.

 

XML을 이용하여 설정하는 방법

Hello Class생성

@Setter
@NoArgsConstructor
public class Hello {
	private String name;
	private Printer printer;

	public String sayHello() {
		return "Hello " + name;
	}

	public void print() {
		this.printer.print(sayHello());
	}

}

Printer interface에 정의되어있는 추상메소드를 이용하여 적용

 

Printer를 참조하는 StringPrinter 클래스 생성

package com.example;

public class StringPrinter implements Printer {
	private StringBuffer buffer = new StringBuffer();

	@Override
	public void print(String message) {
		this.buffer.append(message);
	}

	public String toString() {
		return this.buffer.toString();
	}
}

문자열을 재정의해주는 StringBuffer를 이용한다.

 

Printer를 참조하는 ConsolePrinter생성

package com.example;

public class ConsolePrinter implements Printer{

	@Override
	public void print(String message) {

		System.out.println(message);
	}

	
}

출력이 가능한 클래스를 만든다.

 

메타설정정보를 가지고 있는 beans.xml 생성

<bean id="hello" class="com.example.Hello">
		<property name="name" value="Spring" />
		<property name="printer" ref="printer" />
	</bean>
	<bean id="printer" class="com.example.StringPrinter" />
	<bean id="consolePrinter" class="com.example.ConsolePrinter" />

각각의 bean에 아이디를 설정하고 생성자가 아닌 setter를 이용하기 때문에 property를 이용한다. printer라는 이름을 가진 property는 printer라는 bean을 참조하기때문에  ref로 printer라는 아이디를 가진 빈을 가르킨다.

<xml구조>

실행

1. 실행하기 위한 main 클래스 생성

public class MainClass {
	public static void main(String[] args) {
		ApplicationContext ctx = new GenericXmlApplicationContext("classpath:beans.xml");
		Hello hello = ctx.getBean("hello", Hello.class);
		System.out.println(hello.sayHello());
	}
}

GenericXmlApplicationContext의 상위 인터페이스인 ApplicationContext로 ctx변수를 만들어 Beanfactory가 가지고 있는 getBean이라는 메소드를 사용하여 hello라는 아이디를 가진 bean을 가져온 후 출력한다.

 

2. JUnit을 이용하여 test하는 방법

public class HelloBeanJUnitTest {
	private ApplicationContext ctx;
	
	@Before
	public void init() {
		this.ctx = new GenericXmlApplicationContext("classpath:beans.xml");
	}
	
	@Ignore @Test
	public void test() {
		assertNotNull(this.ctx);
	}
	@Ignore @Test
	public void test2() {
		Hello hello = this.ctx.getBean("hello", Hello.class);
		assertEquals("Hello Spring", hello.sayHello());
	}
    @Test
	public void test3(){
	Hello hello = (Hello)ctx.getBean("hello");
	
	Hello hello2 = ctx.getBean("hello", Hello.class);
	assertSame(hello, hello2);
	}
}

pom.xml에 JUnit라이브러리를 입력 후 maven install를 하여 JUnit Annotaion 실행이 가능하게 해준다.

@Before는 test를 실행하기전 ctx파일에 classpath를 입력하기위한 Annotaion이며 실질적 text는 @Test에서 이루어진다.@ignore은 테스트를 사용하지 않을 때 사용하는 Annotaion이다. 

getBean은 object형이기 때문에 강제형변환을 하는 방법이 있고, 뒤에 클래스명을 입력하는 방법이 있는데 이것은 api에서 확인이 가능하다.

<성공시>

3. SpringFramewor으로 test하는 방법

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:beans.xml"})
public class HelloBeanJunitSpringTest {
	@Autowired
	ApplicationContext context;

	@Test
	public void test1() {
		Hello hello = (Hello) context.getBean("hello");
		assertEquals("Hello Spring", hello.sayHello());
		hello.print();
	}
}

먼저 pom.xml에 Springframework를 추가 후 사용이 가능하다.

@Rinwith은 JUnit과 연동하겠다는 junit소속 Annotaion이며 SpringJUnit4ClassRunner.class를 지정해주면 JUnit이 test를 진행하는 동안 AppicationContext를 만들고 관리하는 작업을 진행해 준다.(Junit4에서만 가능하며 Jupiter에서는 다른 Annotaion사용)

JUnit과는 다르게 @Autowired를 통해 @Before에서 직접 바인딩을 하는 것이 아닌 자동으로 바인딩이 가능한데 클래스를 실행하는 순간 자동으로 @ContextConfiguration에서 지정한 환경설정과 자동으로 바인딩이 될 수 있게 해주는 Annotation이다.

 

Annotaion을 이용하여 설정하는 방법

xml이 아닌 일반 클래스를 생성한다

@Configuration
public class AppCtx {

	@Bean
	public Hello hello() {
		Hello hello = new Hello();
		hello.setName("Spring");
		hello.setPrinter(this.printer());
		return hello;
	}

	@Bean
	public StringPrinter printer() {
		return new StringPrinter();
	}

	@Bean
	public ConsolePrinter consolePrinter() {
		return new ConsolePrinter();
	}
}

일반 자바 클래스가 아니라 환경설정을 위한 클래스이기때문에 @Configuration을 반드시 사용하며 @Bean을 사용하여 bean 객체를 생성한다. xml에서 사용한 id설정은 메소드이름{hello()}이며 클래스명은 리턴타입(Hello)으로 지정한다.

 

3. SpringFramewor으로 test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppCtx.class)
public class HelloBeanTest {
	@Autowired
	private ApplicationContext ctx;
	
	@Test
	public void test1() {
		Hello hello = this.ctx.getBean("hello", Hello.class);
		assertNotEquals("HelloSpring", hello.sayHello());
	}
}
Comments