Multi module Spring Boot project with different context paths - java

As the title says, I'm trying to create a multi module Spring Boot project that has different context paths for each module.
Let's say I have a bunch of core functionality in one module, and let's call it 'core'. This includes defining entities, DAOs and common functionality. I'd like to add two more modules, (for instance 'frontend' and 'admin'), and I'd like that those two modules could run independently from each other (both depending on 'core'). But I'd also like to have the possibility to run them together, and access frontend when the path is '/' and admin when the path is '/admin', which is the part I'm struggling to achieve.
What I've done so far:
I'm using Gradle. I've created a parent module at root level. This parent module contains the just the main method for Spring Boot to init, and depends on both 'frontend' and 'admin' (both which, in turn, depend on 'core'). I've created a Controller on each of these two modules, and if the path is different they work fine. But still, they work as they belong to the same application, and both are mapped to the same context path. I want to be able to map "/login" on each module and let Spring decide where to execute based on context path ("localhost:8080/login" should be mapped to 'frontend' module Controller, "localhost:8080/admin/login" should be mapped to 'admin' module Controller).
Just to clarify, if the approach I'm using is not the best for what I'm trying to achieve, I'm happy to change it.

Related

Spring Boot - Conditionally load module during runtime or compile-time

First of all, I am new to Spring Boot so I am not sure if something like this is possible within the framework.
Let me describe my problem.
I have 10 code repositories. Each repository listens to a data stream, parses the data and updates a database. Due to maintainability issues I plan on bringing it under a single code repository. This new application will be generalized, and certain app specific configurations (for example, which stream should I connect to, the database host) will be retrieved at run-time.
Theoretically, this would allow me to maintain a single code base, but deploy it as 10 separate services based on configurations which is what I need. However, there's a set of java classes that are application specific used to parse the retrieved data. To better understand this refer the diagram below.
Ideally, I need to still maintain these classes in the same repository, but as separate modules. Once the configurations are loaded, the app should be able to load the corresponding module into the application context and initialize the Java classes. The other modules will not be used.
Can I do something like this with Spring Boot? Alternately, even a build time solution is fine if I can create separate builds which can then be deployed separately.
Not sure did I understood it well but why don't try spring profile (https://www.baeldung.com/spring-profiles). You can set for every service different config and with spring.profiles.active in runtime say what configuration will use.
Also something like this could be useful https://www.baeldung.com/spring-reloading-properties

One project with multiple angular app architecture

I need to develop a new project that will contain several AngularJS application and I have a questions about the project architecture.
The solution will behave 5 webapp (for the moment) and the customer can choose the modules he wishes. These applications will be available only on its networks.
I thought two solution
First solution: develop 5 war (easy to deploy war according customer needs)
Second solution: make a unique war (and configure in database which applications will be available)
Regarding the first solution:
I wanted to create a maven module for each webapp + a "core" module that will be included in each webapp module and will contain spring configuration (which is 95% identical between each webapp), entities, dao and some shared services. Do you see any problems to proceed this way?
Concerning the second solution
In fact I do not even know how to do it yet but I think it's doable (maybe with a http filter ?)
So what is the best solution knowing I privilege maintainability over performance?
Basically what you may meed is a project with front-end layer, service layer and DAO layer.
Prepare three of them as separate maven projects and then add them as maven dependencies or create an appropriate package structure in a single project.
In front-end, instead of using 5 different projects you can use a single project with a switching page. from the switching page you can direct requests to corresponding app you want with the aid of spring configured mvc-dispatcher.
folder structure for front-end in my suggestion would be looks like as in below,
-webapp
|_web-inf
|_pages
|_app
|_project A
|_project B
|_scripts
|_projects B's sub module A
|_projects B's sub module B
|_controllers
|_factories
|_model
|_services
|_views
|_projects B's sub module C
|_projects B's sub module D
|_projects B's sub module E
|_project C
|_project D
|_project E
You can map your resources in you application using mvc-dispatcher as below,
<mvc:resources mapping="/projectA/scripts/**" location="/WEB-INF/pages/app/projectA/scripts/"/>
<mvc:resources mapping="/projectB/scripts/**" location="/WEB-INF/pages/app/projectB/scripts/"/>
<mvc:resources mapping="/projectC/scripts/**" location="/WEB-INF/pages/app/projectC/scripts/"/>
<mvc:resources mapping="/projectD/scripts/**" location="/WEB-INF/pages/app/projectD/scripts/"/>
<mvc:resources mapping="/projectE/scripts/**" location="/WEB-INF/pages/app/projectE/scripts/"/>
Hope this would be helpful

Spring 3 Application Context loading

I am a bit familiar with Spring framework but am still having lots of question concerning use of spring from project architectural view point. Now I am setting up Spring 3 and a Maven web application and am willing to try out all the the fancy component-scan's and autowiring features however this is where I get confused.
I am trying to break the project into sub-modules. And at some point these sub-modules may include something-context.xml in classpath*:resource/META-INF, like for instance when I will want to define a datSource related stuff in a separate module. So that's fine spring let's you load context files from within class-paths of all of the jars.
But here is where it gets vague - say I am using component scan. I am obviously using spring DispatcherServlet and it needs a servlet context to be loaded, and then there is a global application context parameter specified in web.xml contextConfigLocation.
So now servlet context config has a component-scan feature enabled for com.mycom.project.controllers and context loaded in the global contextConfigLocation has a context loaded with component scan feature for package com.mycom.project also searches for classpath*:META-INF/spring/*-context.xml.
So my question is - does this load controller's twice given that component scan is used for a for com.mycom.project.controllers and com.mycom.project? Or is it all loaded into one huge container and the contextConfigLocation parameter for either DispatcherServlet or global declaration is sort of access issue ? As in DispatcherServlet will reach only what's defined in servlet-context.xml but won't be able to use anything else?
And if my assumption is wrong, could I have a suggestion on how to manage multi-module project issues?
Thanks.
Yes, you might run into trouble. See this link for how to solve your problem.
#Service are constructed twice
The way you proceed when creating modules seems valid to me. You have a context.xml file for each module and all will get loaded once you load the application. Your modules are self-contained and can also be used in different environments. That's pretty much the way I'd also do it.

Autowiring beans from a different module

I have a big application which i want to break up into manageable modules. I am using spring with Jpa (Hibernate as a provider). I came up with a structure where I have a core module containing all the entity and dao classes, and the other modules make use of the core module regarding persistence, and each one of them will have its own set of service classes and controllers.
All Jpa and spring configuration files are in the core module. With this setup I am facing a problem of autowiring dao beans in the modules making use of the core module. So my question is, is it possible to autowire beans from the core module in the other modules (or probably use a context across modules)? I am also open to suggestions regarding the structure, if there is a better way of doing it.
Thanks
The Core Module must be the parent Spring context that must be setted in each child context module. By this way there's no ploblem with autowiring
Every child context can reach all beans from parent, but be aware of that parent can't see the children
Depending on how you've configured your application, you can do this in several ways, i. e.
Distributing your core module in a separate jar to every module, as it's described in this article Sharing a spring context across multiple Webapps
Programatically, having your core spring xml in each child module, you can do this:
ClassPathXmlApplicationContext parentAppContext = new ClassPathXmlApplicationContext();
parentAppContext.setConfigLocation("spring-core.xml"); // this is your core spring xml
parentAppContext.refresh();
ClassPathXmlApplicationContext moduleAppContext = new ClassPathXmlApplicationContext();
moduleAppContext.setConfigLocation("others.xml");
moduleAppContext.setParent(parentAppContext);
moduleAppContext.refresh();

Overwrite configuration for Spring project from outside

I'm developing a Spring application which shall be used by any kind of other application, no matter if that is a Spring project, a web application or even a simple single-class console application. The application who uses my project will just have to add the JAR file with my application.
So my project has a static factory class that gets and returns a bean from its Spring context which acts as an access object to access all public available functions of my project.
That part is already working.
But I need the developer of the application that uses my JAR to be able to overwrite certain configurations in my project without editing the config files in the JAR itself. At the moment those settings should be overwritable:
- the data source and hibernate bean configuration
- the jasypt (encryption) bean configuration
- the log4j settings
How do I make those settings overwriteable with configs from outside the jar?
Greetings
touchdown
Maybe a good solution would be a configuration that the user could override, for this take a look into:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java
Specially to #Configuration and #Bean
Maybe you could have a configuration class implemented and the user can override it. After extending the class and overwrite some methods that provides some beans the user shall inform it to your factory that will do nothing else than
new AnnotationConfigApplicationContext(userConfigurationClass);
If you want to replace the complete configuration, than the easyest way would be to have a parametrized factory that takes an alternative configuration file as its argument.
If you need it a bit more fine grain (lets say up to 10 parts), than you can split your application xml in several smaller once, and use again a configurable factory that allows to exchange the smaller xml files.
So I got a solution that is working for me.
I put an general import for override context-XMLs at the bottom of my main application context:
<import resource="classpath*:project/package/config/override/or-*.xml" />
So all the user has to do is to create the package "project/package/config/override" in his classpath (e.g. resource folder) and place matching XML files in it with new bean definitions.

Categories