'스프링'에 해당되는 글 6건

dbcp와 c3p0 커넥션 풀 유지하기 :: 2009/02/17 18:09

JDBC 커넥션 풀을 지원하는 대표적인 오픈소스 중에 아파치 DBCPC3P0가 있다. 이들은 Spring, Hibernate 등과 통합되어 DB 커넥션 풀을 제공하는 DataSource를 구성하여 자주 쓰인다.

오라클이나 MySQL 등 DBMS들은 기본적으로 특정 시간동안 실행이 없으면 해당 세션을 종료하게 된다. 이렇게 종료된 커넥션은 어플리케이션에서 오류를 발생시키게 되므로 커넥션을 유지하기 위한 별도 설정을 필요로 하게 된다. 커넥션을 얻어올 때 커넥션 테스트를 수행하고 실패하면 새로운 커넥션을 생성할 수 있다. 또한 idle 타임에 주기적으로 커넥션 테스트를 수행할 수도 있다.

아래는 dbcp를 이용하여 구성한 스프링 DataSource 설정의 예이다.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="defaultAutoCommit" value="true"/>
    <property name="initialSize" value="5"/>
    <property name="maxActive" value="30"/>
    <property name="maxIdle" value="5"/>
    <property name="maxWait" value="30000"/>
    <property name="validationQuery" value="SELECT 1 FROM DUAL"/>
    <property name="testOnBorrow" value="true"/>
    <property name="testOnReturn" value="false"/>
    <property name="testWhileIdle" value="true"/>
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
</bean>

아래는 c3p0를 이용하여 구성한 스프링 DataSource 설정의 예이다.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
    <property name="driverClass" value="org.gjt.mm.mysql.Driver" />
    <property name="jdbcUrl" value="jdbc:mysql://localhost/testdb" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="initialPoolSize" value="5" />
    <property name="maxPoolSize" value="30" />
    <property name="minPoolSize" value="5" />
    <property name="acquireIncrement" value="3" />
    <property name="acquireRetryAttempts" value="30" />
    <property name="acquireRetryDelay" value="1000" />
    <property name="idleConnectionTestPeriod" value="60" />
    <property name="preferredTestQuery" value="SELECT 1" />
    <property name="testConnectionOnCheckin" value="true" />
    <property name="testConnectionOnCheckout" value="false" />
</bean>

참조:
  - DBCP Configuration: http://commons.apache.org/dbcp/configuration.html
  - C3P0 Configuraion: http://www.mchange.com/projects/c3p0/index.html

스프링 설정에서 null 값 셋팅하는 방법 :: 2008/06/12 16:37

스프링 설정에서 null 값 셋팅하는 방법이다.
부분적인 테스트 수행 시 모든 bean을 참조할 필요가 없을 경우, 정의안된 argument 등에 대해서 null 값 셋팅 시에도 유용하게 사용할 수 있다.

<bean class="SampleBean">
<property name="name"><value></value></property>
</bean>
 
--> sampleBean.setName("") 와 동일.

<bean class="ExampleBean">
<property name="email"><null/></property>
</bean>

--> exampleBean.setEmail(null)과 동일
 

스프링 어플리케이션 컨텍스트 설정 :: 2008/05/15 23:03

스프링 프레임워크의 버전별 어플리케이션 컨텍스트 설정에 대한 간단한 샘플이다.

1. Spring 1.2에서 DTD 기반의 XML 설정을 지원한다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
 "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
 <!-- ========================= DATABASE ============================ -->
 <bean id="propertyConfigurer" 
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
   <list>
    <value>jdbc.properties</value>
   </list>
  </property>
 </bean>
 <bean id="dataSource" 
  class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${jdbc.driverClassName}" />
  <property name="url" value="${jdbc.url}" />
  <property name="username" value="${jdbc.username}" />
  <property name="password" value="${jdbc.password}" />
 </bean>
 <!-- ========================= TRANSACTION ======================== -->
 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource" />
 </bean>
 <!-- ========================= O/R BROKER ========================= -->
 <bean id="exampleBroker" 
  class="org.springmodules.orm.orbroker.BrokerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="configLocation"
   value="classpath:net/java2go/dao/maps/ExampleBrokerSql.xml" />
 </bean>
 <!-- ========================= DAO ================================ -->
 <bean id="exampleDao" class="net.java2go.dao.IBatisExampleDAOImpl">
  <property name="broker" ref="examplenBroker" />
 </bean>
 
 <!-- ========================= SERVICE ============================ -->
 <bean id="exampleService" class="net.java2go.service.ExampleServiceImpl">
  <property name="exampleDao" ref="exampleDao" />
 </bean>
</beans>

2. Spring 2.0에서는 DTD 기반 설정뿐만 아니라 XML 스키마 기반의 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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 <!-- ========================= DATABASE ============================ -->
 <bean id="propertyConfigurer"
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
   <list>
    <value>jdbc.properties</value>
   </list>
  </property>
 </bean>
 <bean id="dataSource"
  class="com.mchange.v2.c3p0.ComboPooledDataSource"
  destroy-method="close">
  <property name="driverClass" value="${jdbc.driverClassName}" />
  <property name="jdbcUrl" value="${jdbc.url}" />
  <property name="user" value="${jdbc.username}" />
  <property name="password" value="${jdbc.password}" />
  <property name="initialPoolSize"
   value="${jdbc.initialPoolSize}" />
  <property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
  <property name="minPoolSize" value="${jdbc.minPoolSize}" />
  <property name="acquireIncrement"
   value="${jdbc.acquireIncrement}" />
  <property name="acquireRetryAttempts"
   value="${jdbc.acquireRetryAttempts}" />
 </bean>
 <!-- ========================= TRANSACTION ======================== -->
 <!-- transaction -->
 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource" />
 </bean>
 <!--tx:annotation-driven transaction-manager="transactionManager" /-->
 <!-- ========================= ASPECT ============================= -->
 <tx:advice id="txAdvice"
  transaction-manager="transactionManager">
  <tx:attributes>
   <tx:method name="*Audit**" propagation="NOT_SUPPORTED" />
   <tx:method name="get*" propagation="SUPPORTS"
    read-only="true" rollback-for="Throwable" />
   <tx:method name="retrieve*" propagation="SUPPORTS"
    read-only="true" rollback-for="Throwable" />
   <tx:method name="verify*" propagation="SUPPORTS"
    read-only="true" rollback-for="Throwable" />
   <tx:method name="check*" propagation="SUPPORTS"
    read-only="true" rollback-for="Throwable" />
   <tx:method name="*" propagation="REQUIRED"
    read-only="false" rollback-for="Throwable" />
  </tx:attributes>
 </tx:advice>
 <bean id="loggingAspect"
  class="net.java2go.aspect.LoggingAspect">
  <property name="thresholdInMills" value="3000" />
 </bean>
 <aop:config>
  <aop:pointcut id="servicePointcut"
   expression="execution(* net.java2go.service..*Service.*(..))" />
  <aop:pointcut id="daoPointcut"
   expression="execution(* net.java2go.dao..*DAO.*(..))" />
  <aop:pointcut id="serviceDaoPointcut"
   expression="execution(* net.java2go.service..*Service.*(..))
    or execution(* net.java2go.dao..*DAO.*(..))" />
  <aop:advisor advice-ref="txAdvice"
   pointcut-ref="servicePointcut" />
  <aop:aspect ref="loggingAspect">
   <aop:around pointcut-ref="servicePointcut"
    method="logProfiling" />
   <aop:after-throwing pointcut-ref="serviceDaoPointcut"
    throwing="ex" method="logException" />
  </aop:aspect>
 </aop:config>
 <!-- ========================= IBATIS ============================= -->
 <bean id="sqlMapClient" 
  class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation">
   <value>sqlmap-config.xml</value>
  </property>
  <property name="dataSource" ref="dataSource" />
 </bean>
 <!-- ========================= DAO ================================ -->
 <bean id="exampleDao" class="net.java2go.dao.IBatisExampleDAOImpl">
  <property name="sqlMapClient" ref="sqlMapClient" />
 </bean>
 
 <!-- ========================= SERVICE ============================ -->
 <bean id="exampleService" class="net.java2go.service.ExampleServiceImpl">
  <property name="exampleDao" ref="exampleDao" />
 </bean>
</beans>

3. Spring 2.5에서 더 많은 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:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-2.5.xsd
  http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
 <!-- ========================= DATABASE ============================ -->
 <context:property-placeholder location="jdbc.properties" />
</beans>

Spring In Action 두번째 판 :: 2007/10/30 09:25

스프링 인 액션
 아마존닷컴이 오랜만에 리모델링을 했다. 왠만해서 잘 디자인을 바꾸지 않던 아마존이..

내가 아는 싸이트 중에 대표적으로 디자인을 안바꾸는 싸이트 중 하나로 무역거래와 관련된 Worldbid.com 이란 싸이트가 있다. 내가 캐나다에 있었을 때 밴치마킹 했던 싸이트인데 밴쿠버 빅토리아 섬에 있고 그 당시 이 분야에서는 No.1 이었다. 사업모델이 우수하고 그 분야에서 초기 선점을 해서 단순해 보이는 싸이트지만 전세계에 회원수도 많고 지금도 탄탄할 것이다.

그런데 5년이 넘도록 디자인이 그대로이다. 이 분야 있는 사람들은 변하는 것을 싫어하나 보다.  

8월 중순에 "Spring In Action" 책을 출간된 이후 바로 주문을 했다. 그런데 그동안 예약주문이 많았던 탓인지 9월 초가 되서야 출고가 되었다. 한국까지 오는데 1~2주 걸려 추석 바로전에 한달이 넘어서 책을 받아봤다.

그동안 이런저런 일로 바쁜 탓에 자세히 못봤는데, 시간이 되는데로 정리를 해볼까 한다.

웹로직 8.1에서 스프링 어플리케이션 배포 :: 2007/08/13 16:39

웹로직8.1에서 스프링 프레임워크를 사용한 war 형태의 웹어플리케이션을 배포할 때
아래와 같은 오류가 발생한 다면..


weblogic.management.DeploymentException:
Exception:weblogic.management.ApplicationException: start() failed.
 Module: batman Error: weblogic.management.DeploymentException: Cannot set web app root system property when WAR file is not expanded - with nested exception:
[java.lang.IllegalStateException: Cannot set web app root system property when WAR file is not expanded]

 at weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.doCommit(SlaveDeployer.java:2423)
 at weblogic.management.deploy.slave.SlaveDeployer$Task.commit(SlaveDeployer.java:2138)
 at weblogic.management.deploy.slave.SlaveDeployer$Task.checkAutoCommit(SlaveDeployer.java:2237)
 at weblogic.management.deploy.slave.SlaveDeployer$Task.prepare(SlaveDeployer.java:2132)
 at weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.prepare(SlaveDeployer.java:2384)
 at weblogic.management.deploy.slave.SlaveDeployer.processPrepareTask(SlaveDeployer.java:866)
 at weblogic.management.deploy.slave.SlaveDeployer.prepareDelta(SlaveDeployer.java:594)
 at weblogic.management.deploy.slave.SlaveDeployer.prepareUpdate(SlaveDeployer.java:508)
 at weblogic.drs.internal.SlaveCallbackHandler$1.execute(SlaveCallbackHandler.java:25)
 at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:219)
 at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:178)


아마도 log4j 설정과 관련이 있을 것입니다.
web.xml 에서 log4j listener 설정 부분을 제거하라.


 <!--
 <listener>
  <listener-class>
   org.springframework.web.util.Log4jConfigListener
  </listener-class>
 </listener>
 -->

 

Spring에서 문자 인코딩 처리 :: 2007/07/04 19:36

스프링을 사용한 웹어플리케이션에서 JSP와 DB 의 인코딩 설정이 모두 정상적인데도,
폼에서 값을 입력하면 글자가 모두 깨져서 나올 때가 있다.

이럴 때는 웹어플리케이션의 web.xml에 필터를 설치하면 해결할 수 있다.
비단 EUC-KR 뿐만 아니라 UTF-8 등의 인코딩도 간단히 설정할 수가 있다.

설정법은 web.xml 에 다음과 같이 필터를 추가한다.

 <!-- 인코딩 필더 설치 -->
 <filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>
   org.springframework.web.filter.CharacterEncodingFilter
  </filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
 </filter>

 <filter-mapping>
  <filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>