spring DM + OSGi

Spring 2015. 12. 30. 11:02

 

spring DM이란:

- spring framework의 Core를 이용해서 Dynamic Module을 지원하는 방식으로서 Server모듈이 개발되어 있다.

주로 OSGi를 이용하게 됨.  REF-SITE(영문)

 

OSGi:

- eclipse의 plug-in에서 주로 사용하던 java용 plug-in개발 framework.

 

 

OSGi를 이용한 spring DM 개발방식 :  REF-SITE(개념),    REF-SITE(실전) 

Posted by yongary
,

JPA방식

Spring 2015. 8. 19. 23:35

REF-SITE 

 

Entity 어노테이션이 RDB테이블이 된다.


@Entity
public class Forum {
    @Id private Long id;
    @Column private String name;
    @Column private String description;
    @Column private Date createdAt;
 
// Omit Getters/Setters....
}


Posted by yongary
,

redis를 HA로 구성했을 경우, SDR(spring-data-redis 1.4) 와 jedis커넥션을 이용한 spring과 redis 연동.


RedisSentinelConfiguration 클래스를 이용하면, HA를 지원하는 redis의 이중화 상태에서도 spring을 이용한 redis연동이 가능하다.

java코드로 연동하는 방법은 여러곳에서 나와있으므로, 본 글 에서는

xml을 이용한 DI(Dependency Injection)방식으로   spring과 HA redis를 연동하는 방식을 설명한다.



1. pom.xml 수정   (SDR , jedis를 추가)

이전글과 동일하다. 단 common-pool 대신에 이를 상속받은 JedisPoolConfig을 써봄으로 인해 common-pool은 제거.


<dependency>

<groupId>org.springframework.data</groupId>

<artifactId>spring-data-redis</artifactId>

<version>1.4.0.RELEASE</version>

</dependency>


<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>2.5.1</version>

<type>jar</type>

<scope>compile</scope>

</dependency>




2. application-config.xml 수정


2.1 네임스페이스에  xmlns:p,c, util 추가.


2.2.1 mymaster와 setntinels을 xml로 구성


2.2.2 RedisSentinelContiguration을 이용해서 HA구성.

         => SDR에 미흡한 부분이 하나 존재하여, MySentinelConfiguration  를 별도로 생성해서 이용하도록 함.

             (이유는 아래 xml의 코멘트 참조)   


2.2.3 jedis를 이용한 Pool과 connection구성.


이렇게만 하면 이전 예제와 동일하게 그냥 redisTemplate만을 이용해서 개발하면 자동으로 HA구성을 지원하는 개발이 된다.




<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:p="http://www.springframework.org/schema/p"

xmlns:c="http://www.springframework.org/schema/c"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">


<!-- Uncomment and add your base-package here:-->

<context:component-scan base-package="my"/>


<!-- myster -->

<bean id="myMaster" class= "org.springframework.data.redis.connection.RedisNode" c:host="127.0.0.1" c:port="6379" p:name="mymaster"/>


<!-- Sentinels -->

<bean id="mySent1" class= "org.springframework.data.redis.connection.RedisNode" c:host="127.0.0.1" c:port="26379"/>

<bean id="mySent2" class= "org.springframework.data.redis.connection.RedisNode" c:host="127.0.0.1" c:port="26381"/>

<bean id="mySents" class= "java.util.HashSet">

 <constructor-arg>

  <list>

   <ref bean="mySent1" />

   <ref bean="mySent2" />

  </list>

 </constructor-arg>

</bean>


<!-- RedisSentinelConfiguration: org.springframework.data.redis.connection.RedisSentinelConfiguration" 

2.2.2 이 부분이 유일하게 아직 SDR에서 미흡한 부분이다.  이 부분은 ReidsSentinelConfiguration class 가 

getter와 setter 파라미터가 다른 오류가 발생하므로, 자체 class를 하나 만들어서 해결하였다.

-->

<bean id="redisSentinelConf" class="my.MySentinelConfiguration"

p:master-ref="myMaster"

p:mySentinels-ref="mySents"

/>

<!-- p:sentinels-ref="mySents" : ERROR 발생-->



<!--2.2.3 POOL & Connection-->

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"/>

<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"

    p:use-pool="true"

    p:poolConfig-ref="jedisPoolConfig"

    c:sentinelConfig-ref="redisSentinelConf"

/>

<!--p:host-name="127.0.0.1" p:port="6379" -->



<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

<!-- redis template definition -->

<bean id="redisTemplate"

class="org.springframework.data.redis.core.RedisTemplate"

p:connection-factory-ref="jedisConnFactory"

p:keySerializer-ref="stringRedisSerializer"

p:hashKeySerializer-ref="stringRedisSerializer"

p:valueSerializer-ref="stringRedisSerializer"/>

</beans>





3. JAVA  코드 - 유일하게 추가한 MySentinelConfiguration코드이다.  추가만 해 놓으면 된다.


- 단지, SDR의 getter와 setter의 오류를 피하기 위한 클래스이다. 향후에는 SDR에서 개선이 될 것으로 기대된다.


public class MySentinelConfiguration extends RedisSentinelConfiguration {

MySentinelConfiguration(){

super();

}


public Set<RedisNode> getMySentinels(){

Set<RedisNode> sets=super.getSentinels();

return sets;

}


public void setMySentinels( Set<RedisNode> sentinels){

super.setSentinels(sentinels);

}


}


Posted by yongary
,

spring과 redis연동

Spring 2014. 9. 18. 09:26

SDR(spring-data-redis) 와 jedis커넥션을 이용한 spring을 이용한 redis 연동.


spring에서 redis를 연결하기 위한 기본적인 방법을 커넥션 위주로 설명.

실제로는 redis에 저장할 데이타 class를 별도로 만들어 serialize기능을 이용해 {key,class}형태로 저장하는 방식이 바람직하지만, 여기서는 이 부분은 생략하고 기본적인 연결과정만 설명한다. 


1. pom.xml 수정   (SDR , common-pool,  jedis를 추가)


<dependency>

<groupId>org.springframework.data</groupId>

<artifactId>spring-data-redis</artifactId>

<version>1.4.0.RELEASE</version>

</dependency>

<dependency>

<groupId>commons-pool</groupId>

<artifactId>commons-pool</artifactId>

<version>1.6</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-pool2</artifactId>

<version>2.0</version>

</dependency>

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>2.5.1</version>

<type>jar</type>

<scope>compile</scope>

</dependency>






2. application-config.xml 수정


2.1 네임스페이스에  xmlns:p 추가.

2.2  jedisConnnection, Serializer, redisTemplate 추가.


<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:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <!-- Uncomment and add your base-package here:-->

    <context:component-scan base-package="my"/>


<bean id="jedisConnFactory"

    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"

    p:use-pool="true" p:host-name="127.0.0.1" p:port="6379" />


<bean id="stringRedisSerializer"

    class="org.springframework.data.redis.serializer.StringRedisSerializer"/>


<!-- redis template definition -->

<bean id="redisTemplate"

class="org.springframework.data.redis.core.RedisTemplate"

p:connection-factory-ref="jedisConnFactory"

p:keySerializer-ref="stringRedisSerializer"

p:hashKeySerializer-ref="stringRedisSerializer"

p:valueSerializer-ref="stringRedisSerializer"/>


</beans>



  이 중에서 serializer는 추가하지 않아도 동작은 잘 되지만, 

 기본 serializer로 동작하게 되면 redis에 데이타가 들어갈 때, 앞 부분에 xac xed x00 x05t x00 등의 character가 몇개 들어가게 된다.

(이런 이상한 캐릭터들은 standard serializer에서 사용하는 class정보이다.)




3. JAVA Service 코드


 @Service

public class RedisService implements IRedisService{


@Autowired

private RedisTemplate<String,String> redisTemplate;


public Set<String> keysAll() {


//값을 넣고 싶을 땐, 이렇게..

//redisTemplate.opsForValue().set("abcKey", "valueABC");


return redisTemplate.keys("*");

}



}     


Posted by yongary
,

spring을 이용해서 mongoDB를 연동할 경우 방법은 다음과 같다.


1. pom.xml 수정 : spring-data-mongodb 추가


         <dependency>

       <groupId>org.springframework.data</groupId>

       <artifactId>spring-data-mongodb</artifactId>

       <version>1.5.1.RELEASE</version>

</dependency>

        

      참고: http://projects.spring.io/spring-data-mongodb/

      




2. application-config.xml 수정.   ( 주로 resources/spring/ 밑에 위치)


    2.1 네임스페이스 수정   :  xmlns:mongo 한 줄 및  xsi:schemaLocation 2줄 추가.

    2.2 mongo:db-factory 추가 및  mongoTemplate 추가



   <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:mongo="http://www.springframework.org/schema/data/mongo"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/data/mongo

        http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">

    

<!-- Uncomment and add your base-package here:-->

    <context:annotation-config /> 

    <context:component-scan base-package="my"/> 

   

    <mongo:mongo host="localhost" port="27017"/>

    <mongo:db-factory   dbname="kcdb"/>   


    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">

 <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>

    </bean>  

</beans>





3. Vo(value object) 와 유사한   java파일 작성. ( @Document와  @Id를 포함하도록 한다. )

       

    @Document    //mongoDB에서 persistent한 도메인으로 인식하게 되는 어노테이션. 즉 테이블로 인식.

     public class User{


@Id       // mongoDB의 테이블(category)에서 데이타별 고유id로 자동생성 되는 id에 매핑하기 위함) 

private String id;


private String username;


//setters & getters ... 

}




4. Service에서 mongoTemplate를 이용한 query작성.

 

  @Service

  public class MongoService implements IMongoService{


@Autowired

private MongoTemplate mongoTemplate;

     

  public User getUser(String userName) {


Query query = new Query( where("username").is(userName) );

User user=mongoTemplate.findOne(query, User.class);

return user;

}


   }

Posted by yongary
,

간단한 SQL의 경우 Vo를 바로 return하면 되지만,

복잡한 return형식이 필요할 경우 resultMap을 사용하는 게 편리하다. 


resultMap을 사용해서 데이타를 가져오는 경우

java코드는 100%동일하게 사용하고

mapper xml만 바꿔서 resultMap을 이용하는 예제로 만들어 보면 다음과 같다.


( 이전 글 예제에서 변경되는 부분만 기술 )



4.  UserMapper.xml 에서 resultMap을 사용하도록만 설정.


    <mapper namespace="my.UserMapper">

<resultMap id="userMap" type="my.UserVo">      //UserVo가 실질적인 return type이 됨.

        <id     property="username"    column="username" />

        <result property="age"     column="age" />

      </resultMap>

 

      <select id="user" resultMap="userMap">              //위에서 정의한 userMap을 지칭.

        SELECT  username,age

        FROM    user

        WHERE   username=#{name}

      </select>

    </mapper>




5. VO안에 또 객체가 있다던지 하는 복잡한 경우는 associationcollection으로 해결.  REF

   그리고, 어떤 값에 따라 다른  SQL을 실행할 수 있는 discriminator가 있다.

Posted by yongary
,


1.pom.xml 에 mybatis 추가. (jdbc와 mysql도 추가)

               

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis</artifactId>

<version>3.2.4</version>

</dependency>


<dependency>

  <groupId>org.mybatis</groupId>

  <artifactId>mybatis-spring</artifactId>

  <version>1.2.2</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

<version>3.2.4.RELEASE</version>

</dependency>


<dependency>

 <groupId>mysql</groupId>

 <artifactId>mysql-connector-java</artifactId>

 <version>5.0.8</version>

</dependency>




2. application-config.xml 에 dataSource추가 


    <context:annotation-config /> 
    <context:component-scan base-package="my"/> 

   

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/test" />
        <property name="username" value="root" />
        <property name="password" value="0000" />

    </bean>

    

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:my/*.xml" />
</bean>


    <!--For MapperScan   <mybatis:scan base-package="my" />  스캔방식이 아직 동작안하는 듯 -->

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="my"/>
   </bean>




3.  User table 접근을 위한 UserVo.java와 UserMapper.java

   

public class UserVo {

private String username;

private Integer age;

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

}






public  interface UserMapper {
//public int getManCount();
UserVo getUser(String name);
}



4.  UserMapper.xml 을 resources 밑에 my 밑에 추가


    <mapper namespace="my.UserMapper">

    <select id="getUser" resultType="my.UserVo">

        SELECT  username,age

        FROM    user

        WHERE   username=#{name}

    </select>

</mapper>



5. TestService.java


@Service

public class TestService implements ITestService{


@Resource

private UserMapper userMapper;

public UserVo getUser(String name){

return userMapper.getUser(name);

}

}



Posted by yongary
,

J2EE가 짜증스러웠다고나 할까~ 오랫동안 java 서버개발쪽은 피해 다녔었다.  

근래에 보니 spring이 struts를 완전히 누르고 java framework으로 자리를 확실히 잡은 것 같고

DB연동도 mybatis가 일단 대세를 이루는 것으로 분위기를 파악하고 다시 java 서버쪽에 관심을 가지기로 했다.


<기본 스텝>

0. Eclispe EE버전 설치.  

1. Eclipse -> help-> marketplace에서 find: spring STS(Spring Tool Suite)  검색해서 설치.

2. Tomcat설치 및 Eclipse연동은  이 분의 글 참조:  http://h5bak.tistory.com/136 (tomcat은 7.0x정도로 설치 요망. 현재 tomcat 8.x는 eclipse plugin이 필요한 듯)


3. 프로젝트 생성

new -> other 의 spring 밑에 Spring Project 를 선택한 후,

simple spring-web-maven Project를 선택함.

--> pom.xml 이 자동으로 생성됨. [eclipse Neon에서는 Spring Legacy Project -> Simple Spring Web Maven 임]

( 단, NONE-WEB project일 경우에는 Simple Spring Maven 정도 선택하고

main에서 ClassPathXmlApplicationContext 를 이용함.)



4. new->other->spring   bean configuration File.  add.해서 DI(IOC) 코딩.

  파일명은 application-config.xml 로 하고 (bean, context 최상위꺼 하나씩 필수 선택)

   src/main/resources/spring/application-config.xml 인데.. eclipse neon에서는 자동 생성이 됨.





Posted by yongary
,