Какой-либо демонстрационный проект Spring с открытым исходным кодом это больше, чем PetClinic? [закрытый]

53
задан Arthur Ronald 7 August 2010 в 05:33
поделиться

4 ответа

Посмотрите Apache CXF . Он использует Spring.

3
ответ дан 7 November 2019 в 08:26
поделиться

Некоторые кандидаты:

  • Spring's PetStore

  • AppFuse - В AppFuse используется Spring Framework благодаря поддержке Hibernate/iBATIS, декларативным транзакциям, связыванию зависимостей и развязке уровней.

  • Equinox (он же AppFuse Light) - простое CRUD-приложение, созданное в рамках Spring Live.

  • Spring by Example - различные примеры Spring плюс некоторые загружаемые библиотеки.

  • Tudu Lists - Tudu Lists - это J2EE приложение для управления списками дел. Оно основано на JDK 5.0, Spring, Hibernate и AJAX-интерфейсе (с использованием фреймворка DWR).

  • spring-petstore

7
ответ дан 7 November 2019 в 08:26
поделиться

Я работаю в большой компании медицинского страхования, где мы активно используем Spring в бэкенде. Я покажу вам, как строится модульное приложение.

Скелет WEB-INF без каталога classes

ar
    WEB-INF
        web.xml
        /**
          * Spring related settings file
          */
        ar-servlet.xml
        web
            moduleA
                account
                    form.jsp
            moduleB
                order
                    form.jsp

Скелет каталог 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. Это ключ, необходимый для запуска convention-over-configuration в Spring MVC. Как ??? полагаться на ControllerClassNameHandlerMapping

WEB-INF/ar-servlet.xml Обратите внимание на свойство basePackage, которое означает поиск любого @Controller класса в br.com.ar.view пакете. Это свойство позволяет строить модульные @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 извлечет путь между контекстным путем и расширением файла - выделено выше. Прочитаем извлеченный путь справа Налево

  • form имя метода
  • account неквалифицированное имя класса без суффикса Controller
  • moduleA пакет, который будет добавлен к свойству basePackage

что переводится как

br.com.ar.web.moduleA.AccountController.form

Ok. Но как Spring узнает, какое представление показывать? Смотрите здесь

И о persistence связанных с этим вопросах ???

Прежде всего, смотрите здесь как мы реализуем репозиторий. Обратите внимание, что каждый запрос связанного модуля хранится в связанном с ним пакете хранилища. См. скелет выше. Здесь показан 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 dataSource в методе @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. Имейте это в виду

18
ответ дан 7 November 2019 в 08:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: