Spring+HibernateEntityManager(Spring+DDDっぽく編 その4)

アプリケーション層

アプリケーションは、ドメインの概念と実装を、アプリケーション形作るための階層です(とおいらは思っている)。そのため、アプリケーションの起動部分や、インスタンスの生成やら生成されたインスタンス間の依存関係の設定なども含まれます。

ということで、おいら的には、DIコンテナが扱う情報はアプリケーション層に所属していると思っています。

たまに、DI コンテナの設定ファイル上に制御構文やスクリプト等を入れるような話を聞くことがありますが、それがアプリケーション層以外に含まれるべきものであれば、おいら的にはオススメしないかな。

Main クラス(application/src/main/java/application/Main.java)

サンプルアプリケーションのクラスです。

package application;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import domain.entity.User;
import domain.service.UserService;

/**
 * {@link User} を新規作成し、DB に保存するサンプルプログラム。
 * 
 * @author beyondseeker
 * @version $Id$
 */
public class Main {
    
    /**
     * メイン
     * 
     * @param args
     *            未使用
     */
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        
        // ApplicationContext の取得
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        
        // UserService の取得
        UserService userService = (UserService) ctx.getBean("userService");
        
        // User を新規作成
        User user = userService.newUser();
        user.setName("Kumapiyo");
        
        // User を DB に保存。
        userService.registerUser(user);
        
    }
    
}
persistence.xml

JPA のpersisntence unit の定義ファイルです。

ほとんどの設定は、beans.xml のほうにまとめています。

<persistence
  xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
  version="1.0"
>
  <persistence-unit name="manager" transaction-type="RESOURCE_LOCAL" />
</persistence>
beans.xml

Spring Framework の定義ファイルです。

<?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.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
">

  <!-- Actual DataSource -->
  <bean id="rawDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <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="" />
  </bean>

  <!-- LazyConnectionDataSourceProxy -->
  <bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
    <property name="targetDataSource" ref="rawDataSource" />
  </bean>

  <!-- Transaction Manager -->
  <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
  </bean>

  <!-- JpaVendorAdapter  -->
  <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

  <!-- EntityManagerFactory -->
  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="persistence.xml" />
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaProperties">
      <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
        <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
      </props>
    </property>
  </bean>

  <!-- EntityManager -->
  <bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
  </bean>

  <!-- Transaction Advice -->
  <tx:advice id="readWriteAdvice" transaction-manager="txManager">
    <tx:attributes>
      <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
  </tx:advice>

  <!-- Entity -->
  <bean id="user" class="domain.entity.UserImpl" scope="prototype" />

  <!-- Service -->
  <bean id="userService" class="domain.service.UserServiceImpl">
    <lookup-method name="newUser" bean="user"/>
    <property name="entityManager" ref="entityManager"/>
  </bean>

  <!-- aop -->
  <aop:config>

    <!-- for read-write operations -->
    <aop:pointcut
      id="readWriteOperationPointCut"
      expression="execution(* domain.service.UserServiceImpl.registerUser(..))"
    />
    <aop:advisor
      advice-ref="readWriteAdvice"
      pointcut-ref="readWriteOperationPointCut"
    />

  </aop:config>

</beans>

これで、各階層が一通り揃いましたー (`・ω・´)

メモ

メモ