Search code examples
springmaven-2applicationcontext

Application Context in multi module maven project - Spring


I have a hard time understanding how application context work in multi module project.

Lets say I have a WAR Application "App". App has Jars A, B and C. A has a pom dependency on B and C has pom dependency on B. So can the beans defined in A be used in C as they are packaged in WAR file and are loaded at run time.

The application-context files of A, B and C are imported in WAR application.


Solution

  • Yes it is possible. Here is why:

    Simply because Spring is able to scan the classpath of the your application (if you are using the java annotation, @ComponentScan('com') will load every class you have in the package com.**).

    If you are only running your JAR C with its dependencies, and you are loading every class in a particular package for instance, then you will be fine, you won't have any surprises.

    The same if you do A and B.

    But if you use A, B and C, and you have Spring scanning your packages (some common packages between A and C for instance), then you can have beans declared by A and beans declared by B. Which could some error if you thought you were having only one bean of type Datasource, by you have one in A and one in C.

    Here is an example:

    A has a DataSource.

    package com.my.datasource;
    
    @Configuration
    public class MyConfigurationA() {
        @Bean
        public DataSource datasource() {
            //return new datasource...
        }
    }
    

    C has a DataSource.

    package com.my.datasource;
    
    @Configuration
    public class MyConfigurationC() {
        @Bean
        public DataSource datasource() {
            //return new datasource...
        }
    }
    

    And B declared a JdbcTemplate :

    package com.my.template;
    
    @Configuration
    public class MyConfigurationB() {
        @Bean
        public JdbcTemplate template(DataSource ds) {
            return new JdbcTemplate(ds);
        }
    }
    

    If you run: - C + B -> 1 DataSource + 1 JdbcTemplate. OK ! - A + B -> 1 DataSource + 1 JdbcTemplate. OK ! - A + C + B -> -> 2 DataSources + 1 JdbcTemplate. KO !

    This situation will happen if the WAR you deploy also has a @ComponentScan("com.my").

    So yes, it is possible to have access of bean defined in A in C, but this can be like hidden dependencies, you code is unclear, the execution is uncertain and could fail like succeed without you knowing what is going on.

    Is it clearer ?