spring XML 선언부

 

<?xml version="1.0" encoding="UTF-8"?>
<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-3.1.xsd">
   
   
    <!--
     datasource 설정(propertyConfigurer 활용)
     com.synervelly.common.web.dataaccess 여기서 다른 객체를 받는다.
    -->
    <alias name="dataSource-${First.DbType}"  alias="dataSource1" />
    <alias name="dataSource-${Second.DbType}" alias="dataSource2" /><!-- 다른 데이터 소스를 받을수 있음. -->
       
   
    <!-- Oracle -->
    <bean id="dataSource-oracle" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${First.DriverClassName}"/>
        <property name="url" value="${First.Url}" />
        <property name="username" value="${First.UserName}"/>
        <property name="password" value="${First.Password}"/>
        <property name="initialSize" value="10"/>
        <property name="maxActive" value="10"/>
        <property name="maxIdle" value="5"/>
        <property name="maxWait" value="10000"/>       
    </bean>
   
     <!-- MS-SQL2008 -->
    <bean id="dataSource-mssql" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${Second.DriverClassName}"/>
        <property name="url" value="${Second.Url}" />
        <property name="username" value="${Second.UserName}"/>
        <property name="password" value="${Second.Password}"/>
        <property name="initialSize" value="10"/>
        <property name="maxActive" value="10"/>
        <property name="maxIdle" value="5"/>
        <property name="maxWait" value="10000"/>       
    </bean>   
</beans> 

위 파란색 부분은 프로퍼티 값에서 가져와 입력되는 점을 참고 하시면 됩니다.

ibatis  XML

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd          
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">

    <!-- lob Handler -->
    <bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true" />

    <!-- SqlMap setup for iBATIS Database Layer -->
    <bean id="sqlMapClient1" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocations">
            <list>
                <value>classpath:config/sqlmap/${First.DbType}/*.xml</value>
            </list>
        </property>
        <property name="dataSource" ref="dataSource-${First.DbType}"/>
        <property name="lobHandler" ref="lobHandler"/>
    </bean>
   
   
     <!-- SqlMap setup for iBATIS Database Layer -->
    <bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocations">
            <list>
                <value>classpath:config/sqlmap/${Second.DbType}/*.xml</value>
            </list>
        </property>
        <property name="dataSource" ref="dataSource-${Second.DbType}"/>
        <property name="lobHandler" ref="lobHandler"/>
    </bean>
   
   
   
  
     
</beans>   
 

 

위와같이 선언 하면 각 각 2개의 데이터 소스를 사용할 수 있다.

DAO 부분

 

public class WebAbstractSecondDAO  extends SqlMapClientDaoSupport {
  
    protected WebAbstractSecondDAO() {
           }

    /**
     * Annotation 형식으로 sqlMapClient 를 받아와 이를
     * super(SqlMapClientDaoSupport) 의 setSqlMapClient
     * 메서드를 호출하여 설정해 준다.
     * @param sqlMapClient  
     */
    @Resource(name = "sqlMapClient1")
    public void setSuperSqlMapClient(SqlMapClient sqlMapClient) {
        super.setSqlMapClient(sqlMapClient);
    }

     } 

 

이노테이션을 이용하여

리소스를 주입힌다 .

 @Resource(name = "sqlMapClient1") 이부분

 

 

 

Spring Bean 정보는 싱글톤 객체로 생성되기 때문에

메모리에 존재한다고 보면 된다 .. 

 

ApplicationContext appContext = ContextLoaderListener.getCurrentWebApplicationContext();

(SqlMapClient) appContext.getBean("sqlMapClient"); 

위 방식으로 빈이름 sqlMapClient 과 케스팅 클레스 SqlMapClient 형태로 변환하면 내가 등록한 BEAN 정보를 가지고 올수 있다.

스프링 + quzrtz로 스케줄 관리

 

Spring 기반으로 반복적인 일을 하고 싶을떄 사용한다.

 

적용 범위

1. 특정 요일 특정 시간때 해당 프로세스를 실행 하고 싶을떄

2. 특정 초 (5초단위)마다 프로세스를 생항할떄.

 

적용

 maven

 <!-- Quartz framework -->
  <dependency>
   <groupId>org.quartz-scheduler</groupId>
   <artifactId>quartz</artifactId>
   <version>1.8.6</version>
  </dependency>

개발  -  QuartzJobBean  상속받아 executeInternal 메소드를 제정의 해준다.

public class JobSchedulerOpenAPI extends QuartzJobBean {
 private Logger logger = Logger.getLogger(this.getClass());
 protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
  
  logger.info("###################### 시작  ########################");
  //개발 할 내용
  logger.info("###################### 종료   ########################");
  
 }
}
 

 

스프링 XML 등록  ( 주기적으로 10초마다 실행 예 )

 

 <!-- 빈을 등록한다 -->

<bean name="jobSchedulerOpenAPI"  class="org.springframework.scheduling.quartz.JobDetailBean">

   <!-- 개발한 클레스 -->
  <property name="jobClass"   value="com.wf.weather.quartz. job.JobSchedulerOpenAPI" />
 </bean> 

 

 

<!-- 방법 1 -->
 <bean id="cronTriggerOpenApi" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <!-- 시작시 실생 되고 주기적으로 될떄 SimpleTriggerBean 을 사용한다 -->
  <property name="jobDetail" ref="jobSchedulerOpenAPI" />
  <property name="startDelay" value="1000"/>
  <property name="repeatInterval" value="900000"/>
 </bean>

 

 

<!-- 방법2 -->

<bean name="jobSchedulerFeedback"  class="org.springframework.scheduling.quartz.JobDetailBean">
  <property name="jobClass"   value="com.wf.weather.quartz.job.obSchedulerFeedback" />
 </bean> 
 <bean id="cronTriggerOpenApi" class="org.springframework.scheduling.quartz.CronTriggerBean">
  <property name="jobDetail" ref="jobSchedulerOpenAPI" />
  <property name="cronExpression" value="0 10 2 * * ?" />
 </bean>

 

 

<!-- Scheduler -->
 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="jobDetails">
   <list>
       <ref bean="jobSchedulerOpenAPI" />
       </list>
  </property>  
  <property name="triggers">
   <list>
        <ref bean="cronTriggerOpenApi" />
       </list>
  </property>  
 </bean>

 

 

 

 

설명

방법 1은 org.springframework.scheduling.quartz.SimpleTriggerBean 을 이용하여 프로세스를 실행한다 .

startDelay 시작후 몇초후 부터 실행 될 것인지 확인

 

방법 2은 org.springframework.scheduling.quartz.JobDetailBean을 이용하여 특정 시간 날짜 등을 지정하여 처리하는 방법

cronExpression 설정 방법은 아래 참고

--> http://dev.anyframejava.org/docs/anyframe/plugin/scheduling/4.5.3/reference/html/ch03.html

 

 

 

스케줄 처리 부는 org.springframework.scheduling.quartz.SchedulerFactoryBean  에서 처리한다.

 

 

 

 

 

 

1. 개발 시 고려 사항 및 문제 점 

 날씨 정보 API 하루 REQUEST 횟수가 500으로 제한 되어있어

 최소 한의 비용을 들이기 위해 날씨 정보와 API 키값을 서버에서 관리 하여 처리 하도록 하고

 날씨 OPEN API 쪽으로 최소한으로 요청하여  처리비용을 최소하 한다. 

 빠른 속도를 위하여 날씨 정보는 한번 요청한뒤 DB와 케쉬 시스템을 이용하여 빠른 처리를 할수 있도록 한다. 

 각 지역마다 시간대가 서버와 틀리기 때문에  서버 시간과 지역 시간을 비교하여  시간때를 마쳐 보내야한다.

# 관리 요소

1. OPEN API 키 사용현황 관리

2. 날씨 정보를 주기적으로 체크하여 케쉬 저장 하여 사용자에게 제공한다.

3. 서버 시간과 사용자시간을 일치 시킨다.

4. 비가 오는지 안오는지 판단 하여 PUSH를 보낸다.

5. 날씨 정보를 WEB SERVICE로 제공한다 ( JSON  )

5. GIS 위치로 날씨 해당 지역의 날씨 정보를 알아 낸다.

 

 

 

1. DB 설계 

 

 

 

 

2. CLASS 다이어 그램