我有一个现有的"遗产" 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文件模块的依赖项。
简而言之......任何帮助都会非常感激!谢谢!