我已经阅读了spring doc和PetClinic示例项目。就像看到一些用Spring完成的更大的现实世界项目。感谢。
答案 0 :(得分:104)
答案 1 :(得分:18)
我在一家大型医疗保险公司工作,我们在后端大量使用Spring。我将向您展示如何构建模块化应用程序。
没有班级目录的Skeleton WEB-INF
ar
WEB-INF
web.xml
/**
* Spring related settings file
*/
ar-servlet.xml
web
moduleA
account
form.jsp
moduleB
order
form.jsp
Skeleton classes 目录
classes
/**
* Spring related settings file
*/
ar-persistence.xml
ar-security.xml
ar-service.xml
messages.properties
br
com
ar
web
moduleA
AccountController.class
moduleB
OrderController.class
br
com
ar
moduleA
model
domain
Account.class
repository
moduleA.hbm.xml
service
br
com
ar
moduleB
model
domain
Order.class
repository
moduleB.hbm.xml
service
...
请注意 br.com.ar.web 下的每个包如何匹配 WEB-INF / view 目录。它是在Spring MVC中运行约定优于配置所需的密钥。如何 ???依靠ControllerClassNameHandlerMapping
WEB-INF / ar-servlet.xml 注意basePackage属性,这意味着在 br.com.ar.view下查找任何 @Controller 类包。此属性允许您构建模块化的@ Controller的
<!--Scans the classpath for annotated components at br.com.ar.web package-->
<context:component-scan base-package="br.com.ar.web"/>
<!--registers the HandlerMapping and HandlerAdapter required to dispatch requests to your @Controllers-->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<property name="basePackage" value="br.com.ar.web"/>
<property name="caseSensitive" value="true"/>
<property name="defaultHandler">
<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
现在让我们看一下AccountController
package br.com.ar.web;
@Controller
public class AccountController {
@Qualifier("categoryRepository")
private @Autowired Repository<Category, Category, Integer> categoryRepository;
@Qualifier("accountRepository")
private @Autowired Repository<Account, Accout, Integer> accountRepository;
/**
* mapped To /account/form
*/
@RequestMapping(method=RequesMethod.GET)
public void form(Model model) {
model.add(categoryRepository().getCategoryList());
}
/**
* mapped To account/form
*/
@RequestMapping(method=RequesMethod.POST)
public void form(Account account, Errors errors) {
accountRepository.add(account);
}
}
它是如何工作的?
假设您请求http://127.0.0.1:8080/ar/ moduleA / account / form .html
Spring将删除上面突出显示的上下文路径和文件扩展名之间的路径。让我们从右到左阅读提取的路径
被翻译为
br.com.ar.web.moduleA.AccountController.form
确定。但是Spring怎么知道哪个视图显示???见here
关于持久性相关问题???
首先,请参阅here我们如何实施存储库。 请注意,每个相关模块查询都存储在其相关的存储库包中。见上面的骨架。这里显示了ar-persistence.xml注意 mappingLocations 和 packagesToScan 属性
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/dataSource" resource-ref="true">
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations">
<util:list>
<value>classpath:br/com/ar/model/repository/hql.moduleA.hbm.xml</value>
<value>classpath:br/com/ar/model/repository/hql.moduleB.hbm.xml</value>
</util:list>
</property>
<property name="packagesToScan">
<util:list>
<value>br.com.ar.moduleA.model.domain</value>
<value>br.com.ar.moduleB.model.domain</value>
</util:list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.validator.autoregister_listeners">false</prop>
</props>
</property>
</bean>
</beans>
注意我正在使用Hibernate。应正确配置JPA。
事务管理和组件扫描 ar-service.xml在aop中的 br.com.ar 之后注意两个点:pointcut的表达式属性装置
br.com.ar包下的任何包和子包
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="br.com.ar.model">
<!--Transaction manager - It takes care of calling begin and commit in the underlying resource - here a Hibernate Transaction -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:advice id="repositoryTransactionManagementAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="remove" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="find*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<tx:advice id="serviceTransactionManagementAdvice" transaction-manager="transactionManager">
<!--Any method - * - in service layer should have an active Transaction - REQUIRED - -->
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="servicePointcut" expression="execution(* br.com.ar..service.*Service.*(..))"/>
<aop:pointcut id="repositoryPointcut" expression="execution(* br.com.ar..repository.*Repository.*(..))"/>
<aop:advisor advice-ref="serviceTransactionManagementAdvice" pointcut-ref="servicePointcut"/>
<aop:advisor advice-ref="repositoryTransactionManagementAdvice" pointcut-ref="repositoryPointcut"/>
</aop:config>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
</beans>
<强>测试强>
要测试带注释的@Controller方法,请参阅here如何
除了网络图层。请注意我如何在@Before方法
中配置JNDI数据源@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:ar-service.xml", "classpath:ar-persistence.xml"})
public class AccountRepositoryIntegrationTest {
@Autowired
@Qualifier("accountRepository")
private Repository<Account, Account, Integer> repository;
private Integer id;
@Before
public void setUp() {
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
DataSource ds = new SimpleDriverDataSource(new oracle.jdbc.driver.OracleDriver(), "jdbc:oracle:thin:@127.0.0.1:1521:ar", "#$%#", "#$%#");
builder.bind("/jdbc/dataSource", ds);
builder.activate();
/**
* Save an Account and set up id field
*/
}
@Test
public void assertSavedAccount() {
Account account = repository.findById(id);
assertNotNull(account);
}
}
如果您需要一套测试,请执行以下操作
@RunWith(Suite.class)
@Suite.SuiteClasses(value={AccountRepositoryIntegrationTest.class})
public void ModuleASuiteTest {}
web.xml如下所示
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:ar-persistence.xml
classpath:ar-service.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>ar</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ar</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<resource-ref>
<description>datasource</description>
<res-ref-name>jdbc/dataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
我希望它有用。更新架构到Spring 3.0。请参阅Spring参考文档。 mvc schema,据我所知,只在Spring 3.0中得到支持。牢记这一点
答案 2 :(得分:7)
一些候选人:
AppFuse - 在AppFuse中,Spring Framework全程用于其Hibernate / iBATIS支持,声明性事务,依赖性绑定和层解耦。
Equinox(a.k.a. AppFuse Light) - 一个简单的CRUD应用程序,是作为Spring Live的一部分创建的。
Spring by Example - 各种Spring示例以及一些可下载的库。
Tudu Lists - Tudu Lists是一个用于管理待办事项列表的J2EE应用程序。它基于JDK 5.0,Spring,Hibernate和AJAX接口(使用DWR框架)。
答案 3 :(得分:3)
看看Apache CXF。它使用Spring。