Я закончил читать документ spring и образец проекта PetClinic. Точно так же, как увидеть какой-то более крупный проект в реальном мире, выполненный с помощью Spring. Спасибо.
Любой проект с открытым исходным кодом Spring, который больше, чем PetClinic?
Ответ 1
Ответ 2
Я работаю в большой страховой компании, где мы активно используем Spring в backend. Я покажу вам, как создается модульное приложение.
Скелет WEB-INF без каталога классов
ar
WEB-INF
web.xml
/**
* Spring related settings file
*/
ar-servlet.xml
web
moduleA
account
form.jsp
moduleB
order
form.jsp
Скелет каталог классов
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/директории просмотра. Это ключ, необходимый для запуска условной конфигурации в Spring MVC. Как??? полагайтесь на ControllerClassNameHandlerMapping
WEB-INF/ar-servlet.xml Обратите внимание на свойство basePackage, которое означает поиск любого класса @Controller в пакете br.com.ar.view. Это свойство позволяет создавать модульные @Controller's
<!--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 удалит путь между конвейером и расширением файла - выделено выше. Пусть прочитанный извлеченный путь справа Влево
- имя метода формы
- учетное имя неквалифицированного класса без Суффикс контроллера
- moduleA пакет, который будет добавлен в свойство basePackage
который переводится на
br.com.ar.web.moduleA.AccountController.form
Ok. Но как Spring знает, какое представление показать??? См. здесь
И о проблемах персистентности.
Прежде всего, см. здесь, как мы реализуем репозиторий. Обратите внимание, что каждый связанный запрос модуля хранится в соответствующем пакете репозитория. См. Скелет выше. Здесь показано 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 Обратите внимание на Две точки после br.com.ar в атрибуте выражения aop: 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, см. здесь, как
Кроме веб-уровня. Обратите внимание, как настроить JNDI-источник данных в методе @Before
@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. Насколько я знаю, поддерживается только в Spring 3.0. Помните об этом
Ответ 3
Некоторые кандидаты:
-
AppFuse - в AppFuse используется Spring Framework для поддержки Hibernate/iBATIS, декларативных транзакций, привязка зависимостей и развязка слоев.
-
Equinox (aka AppFuse Light) - простое приложение CRUD, созданное как часть Spring Live.
-
Spring по Примеру - Различные примеры Spring плюс некоторые загружаемые библиотеки.
-
Списки Tudu - Списки Tudu - это приложение J2EE для управления списками todo. Он основан на JDK 5.0, Spring, Hibernate и интерфейсе AJAX (с использованием структуры DWR).
Ответ 4
Посмотрите Apache CXF. Он использует Spring.