How to tell Spring manage autowired dependencies in my library? - spring

I have a reusable component that right now uses Spring in order to be properly instantiated, that means that Spring will autowire all the dependencies that my component needs. I want to make this component a maven module and import it to other projects. All the projects that will use this library are using Spring as Dependency Injector. Can Spring still manage the dependencies for my maven module or do I need to do that manually.Are there any best practices for such scenarios? What I basically asking is how to tell spring to manage the dependencies of my library.

Related

How to discover which spring jar includes a spring package and class?

I am upgrading the libraries on a system and am implementing spring boot. But, there are some dependencies that have to be added over and above the spring boot starters, and some of these are Spring classes.
How can I tell which library a package and class is coming from? The documentation for the class does not seem to provide this...
If i'm understanding correctly, what i do is looking for Compile Dependencies in the maven repos.

Is bad practice to have spring boot starter project for starter project?

Spring boot starter project provides extensive set of functionalities auto configured. But for our application we want to have only a subset of functionality. May be only one feature out of the spring boot starter project. So is it advised to have custom starter project on top of spring boot provided starter project to mask some of the features or write new starter project directly from lower level libraries?
Spring boot starter project provides extensive set of functionalities
auto configured
There are two separate concerns you are talking about.
I think the auto configured part is something which is Spring boot's opinionated way of configuring. As an example if in classpath it finds a in-memory database library ( like H2) it automatically creates a datasource (pointing to embedded in-memory database) which is available for autowiring without you writing the configuration in a Java config class. Of course you can create you own datasource of choice by including appropriate driver jar for that database. Similarly lots of other configurations are done by default by classpath scanning and availability of certain jars and classes.
The second part - is more of a dependency issue in general. Say you want to use web mvc part in Spring boot. This will require a consistent set of dependencies and transitive dependencies as well. Rather than finding and declaring the dependency in your build tool of choice ( maven, gradle etc) it has created the concept of starter projects where you simply mention the parent and all the right dependencies would be pulled on. This gives a great way to correctly lock your dependencies. However if you want to include any different version than what is provided by boot starter ( provided there is no compatibility issues with those different versions) you can still add explicitly in your build tool. For e.g., maven will by default include the highest version of a particular dependency among all available via transitive dependencies when it resolves dependency for an artifact.

Spring boot: submodule dependency

I have multi-module spring boot application. I have organized it in such way that it contains web module which has #SpringBootApplication class and several other modules which are being imported by web module (e.g. batch-jobs module).
web module contains all dependencies from spring boot:
compile('org.springframework.boot:spring-boot-starter-batch')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-integration')
...
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
testCompile('org.springframework.boot:spring-boot-starter-test')
etc...
I wonder whether I should include all spring-boot-starter dependencies into this modules or it's better to have pure spring dependencies like here:
dependencies {
compile 'org.springframework:spring-core'
compile 'org.springframework:spring-context'
compile 'org.springframework.integration:spring-integration-java-dsl'
compile 'org.springframework.batch:spring-batch-core'
...
testCompile 'org.springframework:spring-test'
testCompile 'org.springframework.integration:spring-integration-test'
}
Those dependencies are taken anyway from upper dependency-management configuration. Which approach is better? Can you please advise here?
I think this post will be flagged as opinion-based but anyway:
My thoughts on this topic are (or were if I look at spring boot) to explicitly name the dependencies you actively use in your code (and the specific modules). But with spring boot you cannot really match the dependency in your modules against the starters in the 'project'. Of course you may know that a starter-web will provide mvc from looking in the dependencies outside your project but I think that it will be hard for others to get into the definitions if the project
grows and maintain them.
Pure speculative: What if a starter gets an update and drops a dependency in favour of another? Just to give an example: LibX provided by vendorA is now switched to vendorB. You will still have a JSON dependency to vendorA in your module config but also vendorB gets in your classpath. If they have the same fully qualified name...(bam)
You could extract several starters like persistence related ones to the persistence module and web to web and so on.

Structuring Spring application with decoupled modules

I am working on a webapp which uses Primefaces as a view, and I inject Spring beans from other projects into JSF Managed beans.
I have an architectural problem:
I've created separate projects(modules) for each component that I use (Business Logic, Persistence, and others) and also create separate projects with their interfaces.
I want my webApp to depend only on the interface of the Business Logic, and to inject the implementation of the BL using Spring Dependency Injection.
I want to achive this recursively: Business logic to depend only on other interfaces, and to inject implementations using spring.
The problem is that having no dependency in the Maven pom file to the actual implementations, when I deploy the application (on a web logic server) the implementation jars are not deployed, and Spring doesn't find the beans to wire.
Is there a way to achieve decoupling without adding dependencies to actual implementations?
Can I include Spring's bean configuration files from other projects if the projects are not added as dependencies?
Did I figured this decoupling all wrong?
I appreciate your ideas.
Well obviously you need the dependencies in your maven pom else nothing will be included. You can add the dependencies with a scope of runtime which includes them in your final war but not during development (scope compile).
For loading the context of modules you might come-up with a naming convention and/or standard location for your files. With that you could do something like this in your web applications beans xml
<import resource="classpath*:/META-INF/spring/*-context.xml" />
This would load all files ending with -context.xml from the /META-INF/spring directory on the classpath (including jar files).

Configuring Jersey Via XML?

Is it possible to configure Jersey via XML rather than annotations? Here's my issue:
I have a maven multi-module project with the following modules:
client
webservice
shared
In the shared module, I would like to put my basic POJO classes, with minimal dependencies in the Maven POM. The webservice module will require the POJOs to be configured for both Hibernate and Jersey (such as with #XmlRoot and #Entity annotations). The client module has no need for the Hibernate- and Jersey-specific configuration, and having the classes annotated would introduce the dependencies into the client POM.
Normally I actually prefer annotations over XML, but in this particular case I'm trying to keep the design modular and at least somewhat clean.
Any suggestions?
You can annotate the classes and mark hibernate and jersey as optional dependencies. Then the classes are annotated appropriately and your client is free from the extra dependencies.

Resources