2. Core Concept

[Important]Important
Section 1.3, “<springfield:modules>”은 application 구성에 필요한 bean 을 자동으로 생성 등록 한다.

2.1 Architecture Support Beans

Section 1.3, “<springfield:modules>” 은 basePackage 를 기준으로 Section 1.2, “@Springfield” 를 스캔하여 Layered Architecture 에서 각 레이어에 해당하는 Bean 들을 자동 생성, 등록한다. 등록되는 Bean Name 과 Bean Type 은 다음과 같다.

Table 2.1. Auto Register Bean Name & Type

LayerBean NameBean Type
Controller Layer{@Springfield class short name}Repository EntityController<T, Q>
Validator Layer{@Springfield class short name}Validator EntityValidator<T, Q>
Service Layer{@Springfield class short name}Service EntityService<T, Q>
Repository Layer{Entity class short name}Repository EntityRepository<T, ID>


등록 되는 Bean (implementation) Object 는 Section 1.2, “@Springfield” 의 strategy 속성에 따라 결정된다. strategy 속성이 없다면 Section 1.3, “<springfield:modules>” 의 default-strategy 속성을 따른다. default-strategy 도 선언되지 않았다면, Strategy.JPA 로 설정된다.


Section 1.4, “Springfield Example” 에서 등록되는 Bean 은 다음과 같다.

Table 2.3.  Section 1.4, “Springfield Example” Auto Register Bean (implementation) Object

Bean NameBean TypeBean Object
fooController EntityController<Foo, Foo> EntityControllerImpl<Foo, Foo>
fooValidator EntityValidator<Foo, Foo> EntityValidatorImpl<Foo, Foo>
fooService EntityService<Foo, Foo> EntityServiceImpl<Foo, Foo>
fooRepository EntityRepository<Foo, String> JpaRepository<Foo, String>
~ ~ ~
barSearchController EntityController<Bar, BarSearch> EntityControllerImpl<Bar, BarSearch>
barSearchValidator EntityValidator<Bar, BarSearch> EntityValidatorImpl<Bar, BarSearch>
barSearchService EntityService<Bar, BarSearch> EntityServiceImpl<Bar, BarSearch>
barRepository EntityRepository<Bar, Integer> JpaRepository<Bar, Integer>


[Important]Important
Section 1.3, “<springfield:modules>”가 Bean 들을 자동 생성 , 등록하는 과정에서, 해당 이름을 가진 Bean 이 이미 등록 되어 있다면, Section 1.3, “<springfield:modules>” 은 Bean 을 생성 하지 않고 참조만 하게 된다. 이는 각 레이어의 Bean 를 customizing 할 수 있는 방식으로 사용된다.

2.1.1 EntityController

Layered Architecture 에서 Controller Layer 역할을 수행하는 EntityController 는 handle method 가 정의되어 있어서 Section 1.3, “<springfield:modules>” 에 의해 request mapping 된다. EntityController 의 구현체인 EntityControllerImpl EntityService EntityValidator 를 주입 받아서 동작한다.

public interface class EntityController<T,Q> {

	public String find(Boolean pageEnable, Model model, Pageable pageable, Q query, BindingResult errors) throws Exception;
	
	public String read(Model model, T entity, BindingResult errors) throws Exception;
	
	public String createForm(Model model, T entity, BindingResult errors) throws Exception;
	
	public String create(Model model, T entity, BindingResult errors) throws Exception;
	
	public String updateForm(Model model, T entity, BindingResult errors) throws Exception;
	
	public String update(Model model, T entity, BindingResult errors) throws Exception;
	
	public String delete(Model model, T entity, BindingResult errors) throws Exception;
}	
			

2.1.2 EntityValidator

Layered Architecture 에서 Validator Layer 역할을 수행하는 EntityValidator EntityController 의 handle method 에 대응하는 validation method 가 정의되어 있으며 EntityControllerImpl 에 의해 해당 메소드가 호출된다.

public interface EntityValidator<T,Q> {

	public void find(Q target, Errors errors);
	
	public void read(T target, Errors errors);
	
	public void createForm(T target, Errors errors) ;
	
	public void create(T target, Errors errors);
	
	public void updateForm(T target, Errors errors);
	
	public void update(T target, Errors errors);
	
	public void delete(T target, Errors errors) ;	
}
 		

2.1.3 EntityService

Layered Architecture 에서 Service Layer 역할을 수행하는 EntityService EntityController 의 handle method 에 대응하는 service method 가 정의되어 있으며 EntityControllerImpl 에 의해 해당 메소드가 호출된다. EntityService 의 구현체인 EntityServiceImpl EntityRepository org.springframework.transaction.support.TransactionTemplate 를 주입 받아서 동작한다.

public interface EntityService<T, Q>{
	
	public Iterable<?> find(Q query, Pageable pageable);

	public T read(T entity);
	
	public T createForm(T entity);
	
	public T create(T entity) ;
	
	public T updateForm(T entity);
	
	public T update(T entity);
	
	public T delete(T entity);

}
 		

2.1.4 EntityRepository

Layered Architecture 에서 Repository Layer 역할을 수행하는 EntityRepository EntityService 의 service method 에 대응하는 repository method 가 정의되어 있으며 EntityServiceImpl 에 의해 해당 메소드가 호출된다. EntityRepository 의 구현체인 JpaRepository , HibernateRepository , SqlSessionRepository , JdbcRepository 는 관련된 ORM 객체를 주입 받아서 동작한다.

public interface EntityRepository<T, ID extends Serializable> {

	public boolean exists(T entity);
	public boolean exists(ID id);//CrudRepository

	public T findOne(T entity);
	public T findOne(ID id);//CrudRepository

	public <S extends T> S save(S entity);//CrudRepository
	public <S extends T> Iterable<S> save(Iterable<S> entities);//CrudRepository

	public void delete(ID id);//CrudRepository
	public void delete(T entity);//CrudRepository
	public void delete(Iterable<? extends T> entities);//CrudRepository


	public long deleteAll();//CrudRepository
	public long count();//CrudRepository
	public List<T> findAll();//CrudRepository
	//public Iterable<T> findAll(Iterable<ID> ids);//CrudRepository
	public Iterable<T> findAll(Sort sort); //PagingAndSortingRepository
	public Page<T> findAll(Pageable pageable); //PagingAndSortingRepository
	
	
	public long deleteAll(Object queryMethod);
	public long count(Object queryMethod);
	public List<T> findAll(Object queryMethod);
	public List<T> findAll(Object queryMethod, Sort sort);
	public Page<T> findAll(Object queryMethod, Pageable pageable);
	
	public <R, X> R execute(TemplateCallback<R, X> callback);
}
		

2.2 ORM Support Beans

2.2.1 Using JPA

JPA을 지원하고 Spring @Transactional 을 활성화하기 위해 Section 1.3, “<springfield:modules>”은 필요한 Bean 을 등록한다.

<!-- case 1 -->
<beans>
	<jdbc:embedded-database id="yourDataSource" type="HSQL"/>  	
	   
	<springfield:modules base-package="com.yourcompany.yourproject" 
			data-source-ref="yourDataSource" 
	/>
</beans>

<!-- case 2 -->
<beans>
	<bean id="yourEntityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
		...
	<bean/> 
	   
	<springfield:modules base-package="com.yourcompany.yourproject" 
			entity-manager-factory-ref="yourEntityManager"
	/>
</beans>
		

Table 2.4. Auto Register Beans for JPA

Bean Name <!-- case 1 -->Bean Name <!-- case 2 -->Bean Object
yourDataSourceJpa- org.springframework.orm.jpa. LocalContainerEntityManagerFactoryBean
yourDataSourceJpaTransactionManageryourEntityManagerTransactionManager org.springframework.orm.jpa. JpaTransactionManager
yourDataSourceJpaTransactionTemplateyourEntityManagerTransactionTemplate org.springframework.transaction.support. TransactionTemplate

2.2.2 Using Hibernate

Hibernate을 지원하고 Spring @Transactional 을 활성화하기 위해 Section 1.3, “<springfield:modules>”은 필요한 Bean 을 등록한다.

<!-- case 1 -->
<beans>
	<jdbc:embedded-database id="yourDataSource" type="HSQL"/>  	
	   
	<springfield:modules base-package="com.yourcompany.yourproject" 
			data-source-ref="yourDataSource" 
	/>
</beans>

<!-- case 2 -->
<beans>
	<bean id="yourSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
		...
	<bean/> 
	   
	<springfield:modules base-package="com.yourcompany.yourproject" 
			session-factory-ref="yourSessionFactory"
	/>
</beans>
		

Table 2.5. Auto Register Beans for Hibernate

Bean Name <!-- case 1 -->Bean Name <!-- case 2 -->Bean Object
yourDataSourceHibernate- org.springframework.orm.hibernate3.annotation. AnnotationSessionFactoryBean
yourDataSourceHibernateTransactionManageryourSessionFactoryTransactionManager org.springframework.orm.hibernate3. HibernateTransactionManager
yourDataSourceHibernateTransactionTemplateyourSessionFactoryTransactionTemplate org.springframework.transaction.support. TransactionTemplate

2.2.3 Using Mybatis

Mybatis을 지원하고 Spring @Transactional 을 활성화하기 위해 Section 1.3, “<springfield:modules>”은 필요한 Bean 을 등록한다.

<!-- case 1 -->
<beans>
	<jdbc:embedded-database id="yourDataSource" type="HSQL"/>  	
	   
	<springfield:modules base-package="com.yourcompany.yourproject" 
			data-source-ref="yourDataSource" 
	/>
</beans>

<!-- case 2 -->
<beans>
	<jdbc:embedded-database id="yourDataSource" type="HSQL"/>  	
	
	<bean id="yourSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
		<property name="dataSource" ref="yourDataSource"/> 
		...
	<bean/> 
	   
	<springfield:modules base-package="com.yourcompany.yourproject" 
			data-source-ref="yourDataSource"
			sql-session-factory-ref="yourSqlSessionFactory"
	/>
</beans>
		

Table 2.6. Auto Register Beans for Mybatis

Bean Name <!-- case 1 -->Bean Name <!-- case 2 -->Bean Object
yourDataSourceMybatis- org.mybatis.spring.SqlSessionFactoryBean
yourDataSourceTransactionManageryourDataSourceTransactionManager org.springframework.jdbc.datasource. DataSourceTransactionManager
yourDataSourceTransactionTemplateyourDataSourceTransactionTemplate org.springframework.transaction.support. TransactionTemplate

2.2.4 Using JdbcTemplate

org.springframework.jdbc.core.JdbcTemplate을 지원하고 Spring @Transactional 을 활성화하기 위해 Section 1.3, “<springfield:modules>”은 필요한 Bean 을 등록한다.

<beans>
	<jdbc:embedded-database id="yourDataSource" type="HSQL"/>  	
	   
	<springfield:modules base-package="com.yourcompany.yourproject" 
			data-source-ref="yourDataSource" 
	/>
</beans>
		

Table 2.7. Auto Register Beans for JdbcTemplate

Bean NameBean Object
yourDataSourceJdbcTemplate org.springframework.jdbc.core.JdbcTemplate,
yourDataSourceTransactionManager org.springframework.jdbc.datasource.DataSourceTransactionManager,
yourDataSourceTransactionTemplate org.springframework.transaction.support.TransactionTemplate

2.2.5 Transaction

Section 1.3, “<springfield:modules>”@EnableTransactionManagement 를 이용하여 @Transactional 을 활성화 시켜 놓는다.

public class TransactionalService {

    @Transactional("yourDataSourceJpaTransactionManager")                                                              (1)
    public void doSomething() { ... }

    @Transactional                                                                                                     (2)
    public void setSomething() { ... }
}
			

1

@Transactional 의 value 속성에 Bean Name 을 지정하여 사용할 TransactionManager 를 결정 할수 있다.

2

Section 1.3, “<springfield:modules>” 에 의해 는 가장 먼저 등록된 TransactionManager 가 디폴트 @Transactional로 결정된다.

2.3 Web Support Beans

2.3.1 Message

Section 1.3, “<springfield:modules>”는 message 처리를 위해 다음 bean 을 등록 한다.

Table 2.8. Auto Register Beans for Message Support

Bean NameBean Object
messageSourceorg.springframework.context.MessageSource
messageSourceAccessororg.springframework.context.support.MessageSourceAccessor

Section 1.3, “<springfield:modules>”은 basePackage 를 기준으로 "/**/messages" 을 자동 스캔한다. 다음 예시의 messages_ko.xml 와 messages_en.xml 파일이 basePackage 내에 어떤 위치라도 존재한다면 별도의 설정없이 이를 load 한다.

  • messages_ko.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
    	<entry key="foo.title"><![CDATA[한글제목]]></entry>
    	...	
    </properties>			
    				
  • messages_en.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
    	<entry key="foo.title"><![CDATA[Foooooo]]></entry>
    	...	
    </properties>			
    				

2.3.2 Locale

Section 1.3, “<springfield:modules>”에 의해 한 개 이상의 EntityController 가 등록되는 경우, Locale 변경 및 유지를 위해 다음 Bean 을 등록 한다. 요청 파라미터(?locale=ko)를 전달하여 Locale 변경이 가능 하다.

Table 2.9. Auto Register Beans for Locale Support

Bean NameBean Object
localeResolverorg.springframework.web.servlet.i18n.CookieLocaleResolver
springfieldWebmvcMappedLocaleChangeInterceptororg.springframework.web.servlet.i18n.LocaleChangeInterceptor

2.3.3 Validation

Section 1.3, “<springfield:modules>”는 Validation 처리를 위해 다음 bean 을 등록 한다.

Table 2.10. Auto Register Beans for Validation Support

Bean NameBean Object
springfieldWebmvcValidatororg.springframework.validation.beanvalidation.LocalValidatorFactoryBean

도메인 클래스에 JSR-303 Bean Validation 관련 Annotation 을 적용 할 수 있다.

package com.yourcompany.yourproject.foo;

@Springfield
@Entity
public class Foo{
	
	@Id 
	@NotNull
	private String name;
	
	@NotNull
	private Integer age;
	...
}
    	

2.3.4 Multipart

Section 1.3, “<springfield:modules>”는 File Upload , Download 를 위해 다음 Bean 을 등록 한다.

Table 2.11. Auto Register Beans for Multipart Support

Bean NameBean Object
filterMultipartResolverorg.springframework.web.multipart.commons.CommonsMultipartResolver
springfieldBaseMultipartFileHandler MultipartFileHandlerImpl

Section 1.3, “<springfield:modules>”는 파일 저장 위치를 properties-ref 로 설정 할 수 있다. properties-ref 가 선언되지 않은 경우 디폴트 파일 저장 위치를 사용한다.

<beans>

	<util:properties id="yourProp" 
		location="classpath:com/yourcompany/yourproject/config.properties" />


	<jdbc:embedded-database id="yourDataSource" type="HSQL"/>  	
	
	<springfield:modules base-package="com.yourcompany.yourproject" 
			data-source-ref="yourDataSource"
			properties-ref="yourProp"
	/>
	...
</beans>
		
#
# com/yourcompany/yourproject/config.properties
#
springfield.multipart.location=/yourLocation
springfield.multipart.size=1024
		
[Important]Important

Section 1.3, “<springfield:modules>” 의 properties-ref 를 선언하면 Section 1.3, “<springfield:modules>” 의 각종 설정 값을 변경할수 있다.

2.3.5 ViewResolver

Section 1.3, “<springfield:modules>”에 의해 한 개 이상의 EntityController 가 등록되는 경우, ViewName 을 랜더링하기 위해 다음 과 같은 View Resolver Bean 들이 자동 등록된다.

Table 2.12. Auto Register Beans for Resolving View

Bean NameBean Object
springfieldWebmvcRenderThymeleafViewResolver~
springfieldWebmvcRenderJstlViewResolver~
springfieldWebmvcRenderTilesViewResolver~
springfieldWebmvcRenderJsonViewResolver~
springfieldWebmvcRenderXmlViewResolver~
springfieldWebmvcRenderXlsViewResolver~
springfieldWebmvcRenderCsvViewResolver~
springfieldWebmvcRenderDownloadViewResolver~
springfieldWebmvcRenderStreamViewResolver~

2.3.6 Security

Section 1.3, “<springfield:modules>”에 의해 한 개 이상의 EntityController 가 등록되는 경우, spring security 를 사용하는 다음 bean 을 등록 한다.

Table 2.13. Auto Register Beans for Security Support

Bean NameBean Object
springfieldWebmvcSecurityNavigationFactory NavigationFactory
springfieldWebmvcSecurityConfiguration Spring-Security Support Beans ...