Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any open source Spring sample project that's bigger than PetClinic? [closed]

I've finished reading the spring doc and the PetClinic sample project. Just like to see some bigger real world project that's done with Spring. Thanks.

like image 646
Tong Wang Avatar asked Oct 02 '22 14:10

Tong Wang


People also ask

Are there any big Spring Boot open source projects?

Thingsboard which is an IoT platform with the microservice architecture. Built with Spring Boot , Spring Security , Spring Data , Spring MVC etc. Spring Initializr is the backend web API that can quickly generate a sample spring-boot project. It is exactly the backend API that powered the famous start.spring.io.

Is Spring Boot good for large projects?

Spring Boot works well with microservices. The Spring Boot artifacts can be deployed directly into Docker containers. However, some developers don't recommend the framework for building large and monolithic apps.

Why Spring Boot is not suitable for large scale projects?

Spring Boot creates a lot of unused dependencies, resulting in a large deployment file; The complex and time-consuming process of converting a legacy or an existing Spring project to a Spring Boot application; Not suitable for large-scale projects.

What is the use of Spring Boot framework?

Spring Boot helps developers create applications that just run. Specifically, it lets you create standalone applications that run on their own, without relying on an external web server, by embedding a web server such as Tomcat or Netty into your app during the initialization process.


2 Answers

Spring Projects

Powerstone

Tudu Lists

Alfresco Content Management

SpringSide

Plazma

agileexpress

Zksample2

Spring Rich Client

Broadleaf Commerce

OpenERP

HISPACTA

Luigi Open Search Engine

JOSSO

HSE

Java Small Business Platform

jrecruiter

like image 110
Harsha Hulageri Avatar answered Oct 24 '22 07:10

Harsha Hulageri


I work for a big health insurance company where we heavily use Spring in backend. I will show you how a modularized application is built.

Skeleton WEB-INF without classes directory

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

Skeleton classes directory

        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
            ...

Notice how each package under br.com.ar.web matchs WEB-INF/view directory. It is The key needed To run convention-over-configuration in Spring MVC. How to ??? rely on ControllerClassNameHandlerMapping

WEB-INF/ar-servlet.xml Notice basePackage property which means look for any @Controller class under br.com.ar.view package. This property allows you build modularized @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>

Now let's see, for instance, 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);
    }

}

How does it work ???

Suppose you make a request for http://127.0.0.1:8080/ar/moduleA/account/form.html

Spring will remove the path between context path and file extension - highlighted above. Let's read the extracted path from the right To the left

  • form method name
  • account unqualified class name without Controller suffix
  • moduleA package which will be added to basePackage property

which is translated to

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

Ok. But how does Spring know which view to show ??? See here

And about persistence related issues ???

First of all, see here how we implement repository. Notice each related module query is stored at its related repository package. See skeleton above. Here is shown ar-persistence.xml Notice mappingLocations and packagesToScan property

<?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>

Notice i am using Hibernate. JPA should be properly configured.

Transaction management and component scanning ar-service.xml Notice Two dots after br.com.ar in aop:pointcut's expression attribute which means

Any package and sub-package under br.com.ar package

<?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>

Testing

To test annotated @Controller method, see here how to

Other than web layer. Notice how i configure a JNDI dataSource in @Before method

@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);
    }

}

If you need a suite of tests, do as follows

@RunWith(Suite.class)
@Suite.SuiteClasses(value={AccountRepositoryIntegrationTest.class})
public void ModuleASuiteTest {}

web.xml is shown as follows

<?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>

I hope it can be useful. Update schema To Spring 3.0. See Spring reference documentation. mvc schema, As far As i know, is supported just in Spring 3.0. Keep this in mind

like image 19
Arthur Ronald Avatar answered Oct 24 '22 08:10

Arthur Ronald