여지껏 singleton 이외에 다른 scope의 bean을 사용할 일이 없었는데

B3 Tool을 개발하며 필요하게 되었다.

ApiAdaptor의 생성 overhead를 줄이기 위해 spring에 singleton 으로 생성을 했는데

서로 다른 account에 대해 동시에 ApiAdaptor bean을 사용하게 될 경우에 문제가 생길 가능성이 있었다.

방법은 bean에 config 객체를 set 하는 순간 부터 해당 bean을 synchronize 시키는 방법이 있을 수 있었다.

하지만 언제나 synchonize를 시키는 방법은 여러 문제를 발생 시킬 수 있다.

다른 방법을 생각해 보았는데

민차장님이 회의 들어갔다 나온 사이에 session bean을 사용하는 방법을 찾아 주셨다.


spring 2.0 이상 부터 제공되는 session bean 객체를 이용하는데 

config 를 session scope로 선언하고 aop:proxy를 선언한 후 이를 adaptor의 property로 injection을 하게 되면 config 객체가 사용될 때 마다 proxy 기능에 의해 session scope의 객체가 사용되게 된다.

이를 위해서는


<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"  
  xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

 <!-- API Adaptor Object -->
 <bean id="loginConfig"
  class="com.tfsm.apis.oas.config.OasApiConfig" scope="session" >
  <aop:scoped-proxy/>
 </bean>
 <bean id="campaignProxy"
  class="com.tfsm.apis.oas.proxy.implementation.CampaignProxyBean" >
  <property name="oasConfig" ref="loginConfig"/>
 </bean>
</beans>

이를 위해서는 cglib library가 추가로 필요하며
loginConfig가 interface 기반으로 개발되었을 경우 
 <bean id="loginConfig"
  class="interface명" scope="session" >
  <aop:scoped-proxy proxy-target-class="false"/>
 </bean>
로 선언하게 되면 cglib를 사용하지 않게 된다.

이때 web.xml에는 

<listener>
                <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

이외에
<listener>
       <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>      
도 추가 되어야 한다.

http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes

추가로 spring만 사용했을 경우에는 session scope를 사용하는데 큰 문제가 생기지 않으나
zk framework에서 session  scope bean을 사용하게 될 경우

zk.xml 파일에

    <listener>
            <description>ThreadLocal Synchronization Listener</description>
            <listener-class>org.zkoss.zkplus.util.ThreadLocalListener</listener-class>
    </listener>

 <preference>
  <name>ThreadLocal</name>
  <value>
   org.springframework.web.context.request.RequestContextHolder=requestAttributesHolder,inheritableRequestAttributesHolder;
  </value>
 </preference>
를 추가 하여야 한다.

http://forum.springsource.org/archive/index.php/t-50631.html
http://www.zkoss.org/javadoc/3.0.3/zkplus/org/zkoss/zkplus/util/ThreadLocalListener.html

Posted by headiron
,