Generic

개요

Spring4 Generic은 Autowired 및 Qualifired를 보완하여 Generic을 지원합니다.

설명

기존 Autowire 및 Qualifier의 기능에 대하여 확장하여 Spring4에서 추가로 지원하는 Generic 타입의 Autowire기능에 대하여 알아본다.

Autowire 및 Qualifier

Autowiring 예제

다음은 Customer 클래스에 Person property로 Autowire하는 예제이다.

package com.egovframe.common;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
public class Customer {
 
	@Autowired
	private Person person;
	//...
}

Autowire의 문제점

다음과 같은경우 Person에 Autowire로 주입될수 없다.

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<bean 
class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
 
	<bean id="customer" class="com.egovframe.common.Customer" />
 
	<bean id="personA" class="com.egovframe.common.Person" >
		<property name="name" value="GentlemanA" />
	</bean>
 
	<bean id="personB" class="com.egovframe.common.Person" >
		<property name="name" value="GentlemanB" />
	</bean>
 
</beans>

같은 타입이 2개이므로 다음과 같은 오류를 발생시킨다.

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
	No unique bean of type [com.egovframe.common.Person] is defined: 
		expected single matching bean but found 2: [personA, personB]

Qualifier 사용

Qualifier 어노테이션에 personA를 특정하여 처리 할수 있으나 개별적으로 하나하나 지정해야 하는 문제가 있다.

package com.egovframe.common;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
public class Customer {
 
	@Autowired
	@Qualifier("personA")
	private Person person;
	//...
}

Spring 4 Generics

Generic 설정

추상화 클래스 Employee를 구현한 Manager,Admin을 Generic으로 설정한다. 이경우 Spring 4의 Generic에 대하여 Autowire 주입 대상이 된다.

package generic;

import org.springframework.beans.factory.annotation.Autowired;
	 
public class InjectBeans {
    @Autowired
    Employee<Manager> emp1;
    
    @Autowired
    Employee<Admin> emp2;
    
    public void invokeManager(){
        emp1.empSection();
    }
    
    public void invokeAdmin(){
    	emp2.empSection();
    }
}

주입대상 구현 클래스

Employee는 추상클래스이며 상속을 통하여 구현된다. Admin과 Manager는 구현클래스이며 Autowire 어노테이션에의해 자동 주입된다.

package generic;

public abstract class Employee<T> {
    public void printCompanyName(){
        System.out.println("Display : Company Name");
    }
    public abstract void empSection();
}
package generic;

public class Admin extends Employee<Admin>{
    public void empSection(){
        System.out.println("Display : Admin Section");
    }
}
package generic;

public class Manager extends Employee<Manager>{
    public void empSection(){
        System.out.println("Display : Manager Section");
    }
}

수행결과

구현 클래스 각각의 empSection()이 수행되어 다음과 같은 결과가 출력된다.

6월 23, 2015 11:23:54 오전 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1262a85: startup date [Tue Jun 23 11:23:54 KST 2015]; root of context hierarchy
Display : Admin Section
Display : Manager Section

Spring 3에서의 complie 및 실행

Spring 3에서는 complie은 문제가 없으나 runtime시에 Generic 타입에 대한 주입기능이 없으므로 다음과 같은 오류가 발생한다.

6월 23, 2015 10:38:25 오전 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1110f31: startup date [Tue Jun 23 10:38:25 KST 2015]; root of context hierarchy
6월 23, 2015 10:38:26 오전 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@17f70bf: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springMVCConfiguration,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,getManager,InjectBeans,getAdmin]; root of factory hierarchy
6월 23, 2015 10:38:26 오전 org.springframework.beans.factory.support.DefaultListableBeanFactory destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@17f70bf: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springMVCConfiguration,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,getManager,InjectBeans,getAdmin]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'InjectBeans': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: generic.Employee generic.InjectBeans.emp1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [generic.Employee] is defined: expected single matching bean but found 2: getManager,getAdmin
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:633)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
	at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73)
	at generic.SpringMVCApplicationDemo.main(SpringMVCApplicationDemo.java:15)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: generic.Employee generic.InjectBeans.emp1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [generic.Employee] is defined: expected single matching bean but found 2: getManager,getAdmin
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:517)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
	... 12 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [generic.Employee] is defined: expected single matching bean but found 2: getManager,getAdmin
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:870)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:775)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489)
	... 14 more
 
egovframework/rte2/fdl/ioc_container/generic.txt · 마지막 수정: 2015/06/29 20:01 작성자 com
 
이 위키의 내용은 다음의 라이센스에 따릅니다 :CC Attribution-Noncommercial-Share Alike 3.0 Unported
전자정부 표준프레임워크 라이센스(바로가기)

전자정부 표준프레임워크 활용의 안정성 보장을 위해 위험성을 지속적으로 모니터링하고 있으나, 오픈소스의 특성상 문제가 발생할 수 있습니다.
전자정부 표준프레임워크는 Apache 2.0 라이선스를 따르고 있는 오픈소스 프로그램입니다. Apache 2.0 라이선스에 따라 표준프레임워크를 활용하여 발생된 업무중단, 컴퓨터 고장 또는 오동작으로 인한 손해 등에 대해서 책임이 없습니다.
Recent changes RSS feed CC Attribution-Noncommercial-Share Alike 3.0 Unported Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki