Spring Boot Maven多模块配置结构

时间:2018-02-25 20:19:01

标签: java spring maven spring-boot

我有一个现有的"遗产" Spring 4 RESTful应用程序非常有用。我说"遗产"因为它没有使用Spring Boot。所以,现在我从头开始创建一个新的Spring Boot应用程序,并带来java代码包。

旧弹簧配置是这样的:

Maven Parent Module: phonebook (appname)
+ - pom.xml
|
+--- phonebook-entity
+ - pom.xml - compiles to a Jar
+---+ src
+---+----+-main
+---+----+-----+ java
+---+----+-----+ resources
                      phonebook-entity-context.xml
+---+----+-test
+---+----+-----+ java
+---+----+-----+ resources
|
+--- phonebook-dao
+ - pom.xml - compiles to a Jar
+---+ src
+---+----+-main
+---+----+-----+ java
+---+----+-----+ resources
                      phonebook-dao-context.xml
+---+----+-test
+---+----+-----+ java
+---+----+-----+ resources
|
+--- phonebook-service
 + - pom.xml - compiles to a Jar
+---+ src
+---+----+-main
+---+----+-----+ java
+---+----+-----+ resources
                      phonebook-service-context.xml
+---+----+-test
+---+----+-----+ java
+---+----+-----+ resources
|
+--- phonebook-ws
 + - pom.xml - compiles to a Jar
+---+ src
+---+----+-main
+---+----+-----+ java
+---+----+-----+ webapp
+---+----+-----+ resources
                      phonebook-ws-context.xml
+---+----+-test
+---+----+-----+ java
+---+----+-----+ resources

所以,这是项目结构的布局。这也可以在这里看到:https://github.com/tjholmes66/phonebook-backend-rest

XML中的第一个旧应用程序上下文文件名为:phonebook-entity-context.xml,其中的大部分配置如下:

<bean
    class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean
    class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<context:annotation-config />
<context:component-scan base-package="com.opensource.products.phonebook.server" />

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName">
        <value>${hibernate.connection.driver.class}</value>
    </property>
    <property name="url">
        <value>${hibernate.connection.url}</value>
    </property>
    <property name="username">
        <value>${hibernate.connection.username}</value>
    </property>
    <property name="password">
        <value>${hibernate.connection.password}</value>
    </property>
</bean>

<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

    <property name="packagesToScan"
        value="com.opensource.products.phonebook.server.domain" />

    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            <prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop>
            <prop key="useUnicode">true</prop>
            <prop key="useLegacyDatetimeCode">false</prop>
            <prop key="serverTimezone">UTC</prop>
        </props>
    </property>
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="transactionManager"
    class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager" />

<beans profile="default">
    <context:property-placeholder
        location="file:/opt/phonebook/phonebook-ws.properties" />
</beans>

这很好用,这个模块正确编译成一个JAR,因为它是POJO的所有休眠实体,所以不需要进行测试。

下一个模块,即phonebook-dao,具有与实体模块非常相似的结构。这里的pom.xml确实包含appname-entity.jar,效果很好。该模块在/src/main/resources/phonebook-dao.xml下有自己的应用程序上下文xml文件,并具有以下配置:

<import resource="classpath:/phonebook-entity-context.xml" />

这意味着它将从之前的JAR中提取所有配置。 然后,我可以按如下方式编写测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{ "classpath:/spring/phonebook-dao-context.xml" })
@Transactional
public class ContactDaoTest extends TestCase
{ ... }

这很有效....这会编译成一个JAR,其中包含entities.jar。

同样,我们可以重复服务流程 这就是pom.xml包含对phonebook-dao.jar的依赖 还有一个phonebook-services.context.xml,其中包括以下内容:

<import resource="classpath:/phonebook-dao-context.xml" />
...
and then some beans for email configuration in this xml file.

测试也配置如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{ "classpath:/spring/phonebook-service-context.xml" })
@Transactional
public class ContactServiceTest extends TestCase
{ ... }

这些测试效果很好!这将编译成一个phonebook-services.jar,其中包含phonebook-dao.jar,其中包含phonebook-entity.jar。

使用网络服务级别重复该过程....

我花了一段时间来调整这个基础设施并获得所有内容,以便实体可以编译,因此dao可以编译并运行测试,服务可以测试和运行,控制器可以测试和跑。这是我使用Spring&#34; Legacy&#34;完成的完整RESTful电话簿后端。 ......意思是没有Spring Boot就完成了。

现在我正在学习Spring Boot,并将此应用程序移植到Spring Boot。 这个新项目位于:
https://github.com/tjholmes66/spring-boot-phone-book

我正在尝试与Spring&#34; Legacy&#34;相同的结构。电话簿。 我所做的所有研究都取得了一些成功,因此我有一个定义包结构的父项目,然后父pom引用Spring Boot作为它的父级。

第一层是springboot-phonebook-entity模块。 有一个/src/main/resources/application.properties文件,它是一个带有数据库信息等的标准属性文件。我没有这个图层的问题,它编译得很好,没有Spring错误,也没有在这里执行的测试。

在第二层,springboot-phonebook-dao模块 pom.xml包含依赖于:springboot-phonebook-entity.jar 这个jar文件包含application.properties。 除了jar之外,这里没有application.properties,并且此处也没有定义SpringBootApplication。我在包装下面只有一堆接口:com.tomholmes.springboot.phonebook.server.dao;

现在,为了测试这个,我正在做以下事情:

@SpringBootApplication
@PropertySource(value = "classpath:application.properties")
@EntityScan("com.tomholmes.springboot.phonebook.server.domain")
public class TestRepositoryContextConfiguration
{ ... }

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestRepositoryContextConfiguration.class)
@ComponentScan("com.tomholmes.springboot.phonebook.server")
@Transactional
public class BaseDaoTests
{ ... no other code needed here ... }



public class ContactDaoTest extends BaseDaoTests
{
    @Autowired
    private ContactDao contactDao; // repository

    ... all tests here ...
 }

所以,这需要大量的试验和错误,我终于让它运行了。使用Spring Data的测试似乎都很好用!所以,我很高兴。

下一层是springboot-phonebook-service模块,它包含所有业务服务和业务逻辑。 pom.xml确实包含对springboot-phonebook-dao.jar的依赖。服务应该只调用在最后一个模块中编译的DAO代码,我不知道它是否有效。问题是我无法在此时运行测试。

以下是业务代码:

public interface ContactService
{
    List<ContactEntity> getAllContacts();
    List<ContactEntity> getContactsByUserId(long userId);
    ContactEntity getContactById(long contactId);
    ContactEntity add(ContactEntity newContact);
    ContactEntity update(ContactEntity newContact);
    void remove(long contactId);
}

以下是该代码的实现:

@Transactional
@Service("contactService")
public class ContactServiceImpl implements ContactService
{
    @Autowired
   private ContactDao contactDao;

   @Override
   public List<ContactEntity> getAllContacts()
   {
    List<ContactEntity> contactList = (List<ContactEntity>) contactDao.findAll();
    return contactList;
    }

     ... other code ...
}

测试代码配置如下:

 @SpringBootApplication
 @PropertySource(value = "classpath:application.properties")
 @EntityScan("com.tomholmes.springboot.phonebook.server.domain")
 public class TestServiceContextConfiguration
 { ... }

 @RunWith(SpringJUnit4ClassRunner.class)
 @SpringBootTest(classes = TestServiceContextConfiguration.class)
 @ComponentScan("com.tomholmes.springboot.phonebook.server")
 @Transactional
 public class BaseServiceImplTests
 { ... }

 public class ContactServiceImplTest extends BaseServiceImplTests
 {
      @Autowired
      private ContactService service;

    ... test cases ...
  }

现在,我收到一条错误,指出无法加载应用程序上下文。

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.tomholmes.springboot.phonebook.server.dao.ContactEmailDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

这个bean:com.tomholmes.springboot.phonebook.server.dao.ContactEmailDao 在springboot-phonebook-dar.jar中,源代码定义为:

@Repository("contactEmailDao")
public interface ContactEmailDao extends CrudRepository<ContactEmailEntity, Long>
{
List<ContactEmailEntity> findByContact(ContactEntity contact);
}

所以,就是这样......它经历了大量的试验和错误,我只是没有掌握Spring Boot的组合方式。一旦我清除了这个障碍,下一步就是设置最后一层即网络服务。

这个想法是,一旦这些springboot-phonebook-service都测试好了,那么我将把它编译成springboot-phonebook-service.jar文件。

下一层springboot-phonebook-ws将包含一个pom.xml,其中包含springboot-phonebook-service.jar作为依赖项。最后一层应该包含SpringBootApplication,并将编译为WAR文件。这是MAIN应用程序,其余的jar只是这个WAR文件模块的依赖项。

简而言之......任何帮助都会非常感激!谢谢!

0 个答案:

没有答案
相关问题