최초 커밋
commit
af4ed79add
@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.12</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<groupId>cokr.xit.boot</groupId>
|
||||
<artifactId>xit-foundation-starter</artifactId>
|
||||
<version>23.04.01-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>xit-foundation-starter</name>
|
||||
<description>xit-foundation for Spring Boot</description>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>mvn2</id>
|
||||
<url>http://repo1.maven.org/maven2/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>egovframe</id>
|
||||
<url>http://www.egovframe.go.kr/maven/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>egovframe2</id>
|
||||
<url>http://maven.egovframe.kr:8080/maven/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>maven-public</id>
|
||||
<url>http://xit.xit-nexus.com:8081/repository/maven-public/</url>
|
||||
</repository>
|
||||
|
||||
<!--
|
||||
<repository>
|
||||
<id>maven-releases</id>
|
||||
<url>http://xit.xit-nexus.com:8081/repository/maven-releases/</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
-->
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-jasper</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cokr.xit.base</groupId>
|
||||
<artifactId>xit-foundation</artifactId>
|
||||
<version>23.04.01-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*.class</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>maven-snapshot</id>
|
||||
<url>http://xit.xit-nexus.com:8081/repository/maven-snapshots/</url>
|
||||
</snapshotRepository>
|
||||
|
||||
<repository>
|
||||
<id>maven-release</id>
|
||||
<url>http://xit.xit-nexus.com:8081/repository/maven-releases/</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
|
||||
</project>
|
@ -0,0 +1,133 @@
|
||||
package cokr.xit.foundation.boot;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.egovframe.rte.fdl.cmmn.trace.LeaveaTrace;
|
||||
import org.egovframe.rte.fdl.property.impl.EgovPropertyServiceImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser.Feature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import cokr.xit.foundation.ApplicationContainer;
|
||||
|
||||
/**전자정부 프레임웤과 xit foundation을 사용하는 애플리케이션의 공통 Bean들을 설정한다.
|
||||
* @author mjkhan
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "cokr.xit")
|
||||
public class CommonConfig {
|
||||
/**ApplicationContainer를 반환한다.
|
||||
* @return ApplicationContainer
|
||||
*/
|
||||
@Bean
|
||||
public ApplicationContainer applicationContainer() {
|
||||
return new ApplicationContainer();
|
||||
}
|
||||
|
||||
/**AntPathMatcher를 반환한다.
|
||||
* @return AntPathMatcher
|
||||
*/
|
||||
@Bean
|
||||
public AntPathMatcher antPathMatcher() {
|
||||
return new AntPathMatcher();
|
||||
}
|
||||
|
||||
/**ObjectMapper를 반환한다.
|
||||
* @return ObjectMapper
|
||||
*/
|
||||
@Bean
|
||||
public ObjectMapper objectMapper() {
|
||||
ObjectMapper bean = new ObjectMapper();
|
||||
bean.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||
bean.configure(Feature.ALLOW_COMMENTS, true);
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**SessionLocaleResolver를 반환한다.
|
||||
* @return SessionLocaleResolver
|
||||
*/
|
||||
@Bean
|
||||
public SessionLocaleResolver localeResolver() {
|
||||
SessionLocaleResolver bean = new SessionLocaleResolver();
|
||||
bean.setDefaultLocale(Locale.getDefault());
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**LeaveaTrace를 반환한다.
|
||||
* @return LeaveaTrace
|
||||
*/
|
||||
@Bean
|
||||
public LeaveaTrace leaveaTrace() {
|
||||
return new LeaveaTrace();
|
||||
}
|
||||
|
||||
/**RequestMappingHandlerMapping을 반환한다.
|
||||
* @return RequestMappingHandlerMapping
|
||||
*/
|
||||
@Bean
|
||||
public RequestMappingHandlerMapping requestHandlers() {
|
||||
return new RequestMappingHandlerMapping();
|
||||
}
|
||||
|
||||
private Yml yml = new Yml("application.yml", "application.yml");
|
||||
|
||||
/**application.yml의 설정 내용을 읽어 MessageSource Bean을 설정하여 반환한다.
|
||||
* <pre><code> messageSource:
|
||||
* basenames:
|
||||
* - classpath:message/message-common
|
||||
* - classpath:message/authentication-message
|
||||
* - classpath:org/egovframe/rte/fdl/property/messages/properties</code></pre>
|
||||
* @return ReloadableResourceBundleMessageSource
|
||||
*/
|
||||
@Bean
|
||||
public ReloadableResourceBundleMessageSource messageSource() {
|
||||
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
|
||||
bean.setDefaultEncoding("UTF-8");
|
||||
bean.setCacheSeconds(60);
|
||||
|
||||
List<String> basenames = yml.getValues("messageSource.basenames");
|
||||
if (!basenames.isEmpty())
|
||||
bean.setBasenames(basenames.toArray(new String[basenames.size()]));
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**application.yml의 설정 내용을 읽어 EgovPropertyServiceImpl Bean을 설정하여 반환한다.
|
||||
* <pre><code> propertyService:
|
||||
* properties: # 인라인 프로퍼티가 있을 경우
|
||||
* - property0: value0
|
||||
* - property1: value1
|
||||
* extFileName: #외부 프로퍼티 파일이 있을 경우
|
||||
* - encoding: UTF-8
|
||||
* filename: classpath*:properties/your-file-01.properties
|
||||
* - encoding: UTF-8
|
||||
* filename: classpath*:properties/your-file-02.properties</code></pre>
|
||||
* @return EgovPropertyServiceImpl
|
||||
*/
|
||||
@Bean
|
||||
public EgovPropertyServiceImpl propertyService() {
|
||||
EgovPropertyServiceImpl bean = new EgovPropertyServiceImpl();
|
||||
|
||||
Map<String, String> properties = yml.getMap("propertyService.properties");
|
||||
if (!properties.isEmpty())
|
||||
bean.setProperties(properties);
|
||||
|
||||
Set<?> filenames = yml.getMaps("propertyService.extFileName").stream().collect(Collectors.toSet());
|
||||
if (!filenames.isEmpty())
|
||||
bean.setExtFileName(filenames);
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package cokr.xit.foundation.boot;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.egovframe.rte.psl.dataaccess.mapper.MapperConfigurer;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
||||
import cokr.xit.foundation.Assert;
|
||||
import lombok.Setter;
|
||||
|
||||
/**데이터베이스 접속 관련 설정
|
||||
* <ul><li>{@link #dataSource() 데이터소스} 설정</li>
|
||||
* <li>{@link #sqlSession() MyBatis} 접속 설정</li>
|
||||
* <li>{@link #mapperConfigurer() 매퍼} 설정</li>
|
||||
* </ul>
|
||||
* @author mjkhan
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "spring.datasource")
|
||||
@Setter
|
||||
public class DatasourceConfig {
|
||||
private String driverClassName;
|
||||
private String url;
|
||||
private String username;
|
||||
private String password;
|
||||
/*
|
||||
@Value("${spring.datasource.driver-class-name}")
|
||||
private String driverClassName;
|
||||
@Value("${spring.datasource.url}")
|
||||
private String url;
|
||||
@Value("${spring.datasource.username}")
|
||||
private String username;
|
||||
@Value("${spring.datasource.password}")
|
||||
private String password;
|
||||
*/
|
||||
/**데이터소스 Bean을 반환한다. JDBC 접속은 application.yml 파일에 다음과 같이 설정한다.
|
||||
* <pre><code> spring:
|
||||
* datasource:
|
||||
* driver-class-name: JDBC 드라이버 클래스 이름
|
||||
* url: 데이터베이스 접속 URL
|
||||
* username: 데이터베이스 접속 아이디
|
||||
* password: 데이터베이스 접속 비밀번호</code></pre>
|
||||
* @return 데이터소스
|
||||
*/
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
setConfig();
|
||||
return DataSourceBuilder.create()
|
||||
.driverClassName(driverClassName)
|
||||
.url(url)
|
||||
.username(username)
|
||||
.password(password)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void setConfig() {
|
||||
if (driverClassName != null) return;
|
||||
|
||||
try {
|
||||
Yml yml = new Yml("application.yml", "application.yml");
|
||||
driverClassName = yml.getValue("spring.datasource.driver-class-name");
|
||||
url = yml.getValue("spring.datasource.url");
|
||||
username = yml.getValue("spring.datasource.username");
|
||||
password = yml.getValue("spring.datasource.password");
|
||||
} catch (Exception e) {
|
||||
throw Assert.runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**SqlSessionFactoryBean을 반환한다.<br />
|
||||
* MyBatis의 설정 파일들은 다음 경로에 있어야 한다.
|
||||
* <ul><li>MyBatis 설정: classpath:sql/mybatis-config.xml</li>
|
||||
* <li>매퍼 xml: classpath:sql/mapper/**/*.xml</li>
|
||||
* </ul>
|
||||
* @return SqlSessionFactoryBean
|
||||
*/
|
||||
@Bean
|
||||
public SqlSessionFactoryBean sqlSession() {
|
||||
try {
|
||||
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
|
||||
bean.setDataSource(dataSource());
|
||||
|
||||
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||
bean.setConfigLocation(resolver.getResource("classpath:sql/mybatis-config.xml"));
|
||||
bean.setMapperLocations(resolver.getResources("classpath:sql/mapper/**/*.xml"));
|
||||
return bean;
|
||||
} catch (Exception e) {
|
||||
throw Assert.runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**MapperConfigurer를 반환한다.<br />
|
||||
* base package는 cokr.xit로 설정한다.
|
||||
* @return MapperConfigurer
|
||||
*/
|
||||
@Bean
|
||||
public MapperConfigurer mapperConfigurer() {
|
||||
MapperConfigurer bean = new MapperConfigurer();
|
||||
bean.setBasePackage("cokr.xit");
|
||||
bean.setSqlSessionFactoryBeanName("sqlSession");
|
||||
return bean;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package cokr.xit.foundation.boot;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**xit-foundation.jar에 의존하는 spring boot 애플리케이션의 베이스 클래스
|
||||
* <p>설정 파일을 추가하여 사용하는 경우 설정 파일은
|
||||
* <ul><li>클래스패스의 spring 폴더 아래에 있어야 하고</li>
|
||||
* <li>이름은 'context-'로 시작하는 xml이어야 한다</li>
|
||||
* <li>즉 classpath*:spring/context-*.xml 경로에 해당해야 한다.</li>
|
||||
* </ul>
|
||||
* @author mjkhan
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@ContextConfiguration("classpath*:spring/context-*.xml")
|
||||
@Import({
|
||||
CommonConfig.class,
|
||||
ServletConfig.class,
|
||||
MvcConfig.class,
|
||||
DatasourceConfig.class,
|
||||
TransactionConfig.class,
|
||||
})
|
||||
public class FoundationApplication {}
|
@ -0,0 +1,56 @@
|
||||
package cokr.xit.foundation.boot;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.BootstrapWith;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import cokr.xit.foundation.AbstractComponent;
|
||||
import cokr.xit.foundation.UserInfo;
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
import cokr.xit.foundation.test.TestMapper;
|
||||
|
||||
/**Spring Boot에서 xit-foundation을 사용하는 클래스의 단위 테스트 작성을 위한 베이스 클래스.
|
||||
* <p>FoundationTest는
|
||||
* <ul><li>JUnit5를 사용하며</li>
|
||||
* <li>"test" 프로필을 설정한다.</li>
|
||||
* <li>AbstractComponent의 기능을 사용할 수 있다.</li>
|
||||
* </ul>
|
||||
* @author mjkhan
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@BootstrapWith(SpringBootTestContextBootstrapper.class)
|
||||
@ActiveProfiles("test")
|
||||
public class FoundationTest extends AbstractComponent {
|
||||
@Resource(name="testMapper")
|
||||
protected TestMapper testMapper;
|
||||
|
||||
/**DataObject를 반환한다.
|
||||
* @return DataObject
|
||||
*/
|
||||
protected DataObject dataObject() {
|
||||
return new DataObject();
|
||||
}
|
||||
|
||||
/**user를 현재 사용자로 설정한다.
|
||||
* @param user 사용자 객체
|
||||
*/
|
||||
protected void currentUser(UserInfo user) {
|
||||
UserInfo.Provider.get().setUserInfo(user);
|
||||
}
|
||||
|
||||
/**주어진 인자들을 각각 SQL 문자 리터럴로 변환하고, 컴마(,)로 연결하여 반환한다.<br />
|
||||
* SQL의 IN (...) 문장에 조건을 명시하는 것을 돕기 위한 것이다.
|
||||
* @param params 인자
|
||||
* @return 컴마(,)로 연결된 SQL 문자 리터럴
|
||||
*/
|
||||
protected String join(Object... params) {
|
||||
return Stream.of(params).map(obj -> "'" + obj + "'").collect(Collectors.joining(","));
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package cokr.xit.foundation.boot;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.view.BeanNameViewResolver;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
import org.springframework.web.servlet.view.UrlBasedViewResolver;
|
||||
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import cokr.xit.foundation.web.AccessInitializer;
|
||||
|
||||
/**web mvc 설정(기존 dispatcher servlet) 클래스
|
||||
* @author mjkhan
|
||||
*/
|
||||
@Configuration
|
||||
public class MvcConfig implements WebMvcConfigurer {
|
||||
protected static String[] URL_PATTERNS = {"/", "/**/*.do"};
|
||||
|
||||
/**AccessInitializer를 반환한다.
|
||||
* @return AccessInitializer
|
||||
*/
|
||||
@Bean
|
||||
public AccessInitializer accessInitializer() {
|
||||
return new AccessInitializer();
|
||||
}
|
||||
|
||||
/**정적 파일 자원 접근에 대한 설정을 추가한다.
|
||||
* <ul><li>url: /resources/** </li>
|
||||
* <li>위치: /resources/</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry
|
||||
.addResourceHandler("/resources/**")
|
||||
.addResourceLocations("/resources/");
|
||||
}
|
||||
|
||||
/**AccessInitializer를 interceptor로 추가한다.
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(accessInitializer()).addPathPatterns(URL_PATTERNS);
|
||||
}
|
||||
|
||||
/**BeanNameViewResolver를 반환한다.
|
||||
* @return BeanNameViewResolver
|
||||
*/
|
||||
@Bean
|
||||
public BeanNameViewResolver beanNameViewResolver() {
|
||||
BeanNameViewResolver bean = new BeanNameViewResolver();
|
||||
bean.setOrder(0);
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**UrlBasedViewResolver를 반환한다.
|
||||
* @return UrlBasedViewResolver
|
||||
*/
|
||||
@Bean
|
||||
public UrlBasedViewResolver urlBasedViewResolver() {
|
||||
UrlBasedViewResolver bean = new UrlBasedViewResolver();
|
||||
bean.setViewClass(JstlView.class);
|
||||
bean.setPrefix("/WEB-INF/jsp/");
|
||||
bean.setSuffix(".jsp");
|
||||
bean.setExposeContextBeansAsAttributes(true);
|
||||
bean.setOrder(1);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
/**MappingJackson2JsonView를 반환한다.
|
||||
* @return MappingJackson2JsonView
|
||||
*/
|
||||
@Bean
|
||||
public MappingJackson2JsonView jsonView() {
|
||||
MappingJackson2JsonView bean = new MappingJackson2JsonView();
|
||||
bean.setContentType("application/json;charset=UTF-8");
|
||||
bean.setObjectMapper(objectMapper);
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**CommonsMultipartResolver를 반환한다.
|
||||
* @return CommonsMultipartResolver
|
||||
*/
|
||||
@Bean
|
||||
public CommonsMultipartResolver multipartResolver() {
|
||||
CommonsMultipartResolver bean = new CommonsMultipartResolver();
|
||||
int oneGB = 1_073_741_824; // 1GB=1,073,741,824 byte
|
||||
bean.setMaxUploadSize(oneGB);
|
||||
bean.setMaxInMemorySize(oneGB);
|
||||
return bean;
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package cokr.xit.foundation.boot;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.catalina.servlets.DefaultServlet;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.CharacterEncodingFilter;
|
||||
|
||||
import cokr.xit.foundation.web.AccessFilter;
|
||||
|
||||
/**서블릿 설정(기존 web.xml) 클래스
|
||||
* @author mjkhan
|
||||
*/
|
||||
@Configuration
|
||||
public class ServletConfig {
|
||||
protected static String[] URL_PATTERNS = {"/", "*.do"};
|
||||
|
||||
/**CharacterEncodingFilter를 등록한다.
|
||||
* @return FilterRegistrationBean
|
||||
*/
|
||||
@Bean
|
||||
public FilterRegistrationBean<CharacterEncodingFilter> encodingFilter() {
|
||||
FilterRegistrationBean<CharacterEncodingFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new CharacterEncodingFilter("utf-8"));
|
||||
registration.addUrlPatterns(URL_PATTERNS);
|
||||
registration.setOrder(-102);
|
||||
return registration;
|
||||
}
|
||||
|
||||
/**AccessFilter를 등록한다.
|
||||
* @return FilterRegistrationBean
|
||||
*/
|
||||
@Bean
|
||||
public FilterRegistrationBean<AccessFilter> accessFilter() {
|
||||
FilterRegistrationBean<AccessFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new AccessFilter());
|
||||
registration.addUrlPatterns(URL_PATTERNS);
|
||||
registration.setOrder(-101);
|
||||
return registration;
|
||||
}
|
||||
|
||||
/**DefaultServlet를 등록한다.
|
||||
* @return ServletRegistrationBean
|
||||
*/
|
||||
@Bean
|
||||
public ServletRegistrationBean<DefaultServlet> defaultServlet() {
|
||||
ServletRegistrationBean<DefaultServlet> bean = new ServletRegistrationBean<>(new DefaultServlet(), "/resources/*");
|
||||
bean.setLoadOnStartup(1);
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
params.put("debug", "0");
|
||||
params.put("listings", "false");
|
||||
|
||||
bean.setInitParameters(params);
|
||||
return bean;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package cokr.xit.foundation.boot;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
|
||||
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
|
||||
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||
|
||||
/**트랜잭션 설정 클래스.
|
||||
* <p>트랜잭션의 적용 대상은 cokr.xit..service.bean..*ServiceBean 클래스의 메소드들이다.
|
||||
* @author mjkhan
|
||||
*/
|
||||
@Configuration
|
||||
@Aspect
|
||||
@EnableTransactionManagement
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true)
|
||||
public class TransactionConfig {
|
||||
@Resource(name = "dataSource")
|
||||
private DataSource dataSource;
|
||||
|
||||
@Bean
|
||||
public DataSourceTransactionManager txManager() {
|
||||
DataSourceTransactionManager bean = new DataSourceTransactionManager();
|
||||
bean.setDataSource(dataSource);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TransactionInterceptor txAdvice() {
|
||||
RuleBasedTransactionAttribute write = new RuleBasedTransactionAttribute();
|
||||
write.getRollbackRules().add(new RollbackRuleAttribute(Exception.class));
|
||||
|
||||
Properties txAttrs = new Properties();
|
||||
txAttrs.setProperty("*", write.toString());
|
||||
|
||||
TransactionInterceptor bean = new TransactionInterceptor();
|
||||
bean.setTransactionManager(txManager());
|
||||
bean.setTransactionAttributes(txAttrs);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Advisor txAdvisor() {
|
||||
String expression = "execution(* cokr.xit..service.bean..*ServiceBean.*(..))";
|
||||
|
||||
AspectJExpressionPointcut serviceMethod = new AspectJExpressionPointcut();
|
||||
serviceMethod.setExpression(expression);
|
||||
|
||||
AspectJExpressionPointcut requiredTx = new AspectJExpressionPointcut();
|
||||
requiredTx.setExpression(expression);
|
||||
|
||||
DefaultPointcutAdvisor bean = new DefaultPointcutAdvisor();
|
||||
bean.setPointcut(requiredTx);
|
||||
bean.setAdvice(txAdvice());
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
package cokr.xit.foundation.boot;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import cokr.xit.foundation.Assert;
|
||||
|
||||
/**yml 파일 내용을 프로퍼티 형식으로 읽기를 지원하는 유틸리티.
|
||||
* <p>
|
||||
* @author mjkhan
|
||||
*/
|
||||
public class Yml {
|
||||
private Map<String, ?> source;
|
||||
|
||||
/**새 Yml을 생성한다.
|
||||
* @param rootName 프로퍼티 소스의 루트 이름
|
||||
* @param path 클래스패스에서 yml 파일의 경로
|
||||
*/
|
||||
public Yml(String rootName, String path) {
|
||||
load(rootName, path);
|
||||
}
|
||||
|
||||
/**지정하는 yml 파일의 프로퍼티들을 읽어들인다.
|
||||
* @param rootName 프로퍼티 소스의 루트 이름
|
||||
* @param path 클래스패스에서 yml 파일의 경로
|
||||
* @return 현재 Yml
|
||||
*/
|
||||
public Yml load(String rootName, String path) {
|
||||
source = null;
|
||||
try {
|
||||
List<PropertySource<?>> sources = new YamlPropertySourceLoader()
|
||||
.load(rootName, new ClassPathResource(path));
|
||||
if (!sources.isEmpty())
|
||||
source = (Map<String, ?>)sources.get(0).getSource();
|
||||
return this;
|
||||
} catch (Exception e) {
|
||||
throw Assert.runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**지정하는 프로퍼티(아래 참고)의 값을 반환한다.
|
||||
* @param key 키. 프로퍼티 이름
|
||||
* <pre><code> spring:
|
||||
* application:
|
||||
* name: my-application
|
||||
* </code></pre>
|
||||
* @return 지정하는 키의 프로퍼티 값
|
||||
*/
|
||||
public String getValue(String key) {
|
||||
if (source == null) return "";
|
||||
|
||||
Object obj = source.get(key);
|
||||
return obj != null ? obj.toString() : "";
|
||||
}
|
||||
|
||||
/**지정하는 문자열로 시작하는 프로퍼티(아래 참고) 값들을 반환한다.
|
||||
* <pre><code> list:
|
||||
* - item-0
|
||||
* - item-2
|
||||
* - item-3</code></pre>
|
||||
* @param prefix 프로퍼티 접두어
|
||||
* @return 지정하는 문자열로 시작하는 프로퍼티 값
|
||||
*/
|
||||
public List<String> getValues(String prefix) {
|
||||
if (source == null) return Collections.emptyList();
|
||||
|
||||
return getPrefixed(prefix).stream()
|
||||
.map(entry -> entry.getValue().toString())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Map.Entry<String, ?>> getPrefixed(String prefix) {
|
||||
return source.entrySet().stream()
|
||||
.filter(entry -> entry.getKey().startsWith(prefix))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**지정하는 문자열로 시작하는 프로퍼티(아래 참고) 값들을 Map으로 반환한다.
|
||||
* <pre><code> parent:
|
||||
* - property-0: value-0
|
||||
* - property-1: value-1
|
||||
* - property-2: value-2</code></pre>
|
||||
* @param prefix 프로퍼티 접두어
|
||||
* @return 지정하는 문자열로 시작하는 프로퍼티로 된 Map
|
||||
*/
|
||||
public Map<String, String> getMap(String prefix) {
|
||||
if (source == null) return Collections.emptyMap();
|
||||
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||
getPrefixed(prefix).stream().forEach(entry -> putTo(map, entry));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private void putTo(LinkedHashMap<String, String> map, Map.Entry<String, ?> entry) {
|
||||
String key = entry.getKey();
|
||||
key = key.substring(key.lastIndexOf(".") + 1);
|
||||
String val = entry.getValue().toString();
|
||||
map.put(key, val);
|
||||
}
|
||||
|
||||
/**지정하는 문자열로 시작하는 프로퍼티들(아래 참고)을 Map 목록으로 반환한다.
|
||||
* <pre><code> parent:
|
||||
* - property-0: value-0.0
|
||||
* property-1: value-0.1
|
||||
* - property-0: value-1.0
|
||||
* property-1: value-1.1</code></pre>
|
||||
* @param prefix 프로퍼티 접두어
|
||||
* @return 지정하는 문자열로 시작하는 프로퍼티들의 Map 목록
|
||||
*/
|
||||
public List<Map<String, String>> getMaps(String prefix) {
|
||||
if (source == null) return Collections.emptyList();
|
||||
|
||||
return getPrefixed(prefix).stream()
|
||||
.map(entry -> {
|
||||
String str = entry.getKey();
|
||||
return str.substring(0, str.lastIndexOf("."));
|
||||
})
|
||||
.collect(Collectors.toSet()).stream()
|
||||
.map(this::getMap)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
/**xit-foundation 모듈을 Spring Boot 애플리케이션에서 사용할 수 있도록 지원
|
||||
* <ul><li>배포 모듈: xit-foundation-starter-yy.mm.dd.jar</li>
|
||||
* <li>의존 모듈: {@link cokr.xit.foundation xit-foundation-yy.mm.dd.jar}</li>
|
||||
* </ul>
|
||||
*/
|
||||
package cokr.xit.foundation.boot;
|
Loading…
Reference in New Issue