CDI annotated classes used both in EE6 context and Spring DI context - spring

I have an issue concerning a jar declaring CDI annotated beans, and used both in a spring context and an EE6 context.
This jar, say service.jar, contains classes that are annotated with qualifiers (#Qualifier, allows you to declare your own annotations such as #DataAccessObject in order to identify your beans), and has private members annotated with #Inject.
It's compiled with maven, and it's dependency to javax.javaee-api is declared as provided, because these classes are only needed when deployed within an EE6 context.
Though, there's something that I don't understand. In this service.jar, once compiled, and whether I deploy it in an EE6 context or not, the bytecode references classes such as javax.inject.#Inject.
So why my spring application - which has no javax.javaee-api jar in its classpath - is able to load its configuration correctly and run ?
I was even more confused when I learned that spring provides support for #Inject (JSR 330) annotation.
Can anyone enlighten me on that ?
Thanks.

You must not confuse DI (JSR330) and CDI (JSR299). CDI includes DI. All those javax.inject Annotations belong to DI and are supported by many frameworks (spring and guice for example).
If you strictly reduce your jar dependencies to JSR330 (no need to switch Java EE deps for deployment), you will be able to use any of the supporting frameworks.
Checkout this example: http://www.mkyong.com/spring3/spring-3-and-jsr-330-inject-and-named-example/

Related

What's the difference between Spring Boot's #Configuration and #AutoConfiguration?

And most important, what's the reason behind the "Auto" prefix? Classes annotated with #Configuration rather than #AutoConfiguration are less automatic or something?
#Configuration is a spring framework annotation and not strictly bound to spring-boot. It was introduced when spring started to allow programmatic creation of spring-beans as to move forward from xml definitions of beans.
#AutoConfiguration is a spring-boot specific annotation not commonly available in spring framework. The reason it exists, is for external providers that cooperate with spring-boot to be able to mark some classes in some libraries they provide with this annotation as to inform spring-boot that those classes could be parsed and make some initializations during start up of spring application automatically.
So if some regular programmer that develops some application happens to have kafka in dependencies then some beans will automatically be created and added in application context and will be ready for the programmer to use, although he has not defined any configuration for them. Spring-boot already knows this as the kafka provider has already informed by marking some class in the jar they provide with the annotation #AutoConfiguration.
For this reason #AutoConfiguration has some more powerful configurations available as before, after, beforeName, afterName as to allow the provider to specify when the configuration is applied during application startup if some order is necessary.
So this annotation is not to be used from some regular programmer that develops an application using spring-boot. It is for someone that develops a library that other users might use with spring-boot. One such example is kafka library.
For this to work in a spring-boot project #EnableAutoConfiguration is needed as well, to enable auto configuration.
From spring documentation
Spring Boot auto-configuration attempts to automatically configure
your Spring application based on the jar dependencies that you have
added. For example, if HSQLDB is on your classpath, and you have not
manually configured any database connection beans, then Spring Boot
auto-configures an in-memory database.
#Configuration instead is to be used from some regular programmer that develops an application using spring-boot or spring-framework as to inform the framework for which beans should be created and how.
#AutoConfiguration was introduced in 2.7 with the idea to mark all auto-configurations with its dedicated annotation and move away from spring.factories for auto-configuration imports in 3.0 as described in Github issue.
According to Spring documentation:
[#AutoConfiguration] indicates that a class provides configuration that can be
automatically applied by Spring Boot. Auto-configuration classes are
regular #Configuration with the exception that
Configuration#proxyBeanMethods() proxyBeanMethods is always false.
Usually, #AutoConfiguration classes automatically configure an application based on the dependencies that are present on the classpath. Those classes are generally marked as #ConditionalOnClass and #ConditionalOnMissingBean annotations that detect the presence or absence of specific classes.
Additionally, if a configuration needs to be applied in a specific order, you can use the before, beforeName, after, and afterName attributes on the #AutoConfiguration, unlike #Configuration which doesn't provide those attributes.

Spring Boot Dependency only for Dependency Injection Features?

I just started a Compose for Desktop project with Kotlin. So there is no web stuff I am used to. This is why I did not use Spring stuff from the beginning.
However after a while I kind of miss dependency injection ;)
I tried to look for a spring boot / spring framework dependency that only has functionality like #Service, #Component, #Autowired etc. I was not able to find anything. This always was somewhat included into other contexts like Spring-Boot-Web etc.
So my question: Is there a Dependency Injection Only library with spring?

Does Spring Framework come with its own beans?

This text is from the book called Core Java Server Faces:
It is a historical accident that there are two separate mechanisms,
CDI beans and JSF managed beans, for beans that can be used in JSF
pages. We suggest that you use CDI beans unless your application must
work on a plain servlet runner such as Tomcat. The source code for the
book comes in two versions, one with CDI beans (for Java EE 6
application servers) and one with JSF managed beans (for servlet
runners without CDI support).
My question is:
If I use the Spring Framework, and a Tomcat Server, will I need to use one of the beans mentioned above, or does Spring Framework come with its own bean implementations?
As far as I know, Spring Framework supports Dependency Injection. Does it support it if I run the application on Tomcat? Does it mean that I will be using neither the CDI beans nor the JSF Managed means mentioned in this book?
Thank you.
talking about container is more correct than bean implementation. Yes Spring comes with its own container. In fact you can see spring frameworks as a kind of alternative to the full Java EE stack.
Using Spring DI and CDI together has about no interest but you still can use JSF with spring on tomcat although if i would advise you to switch to a Java EE 6 web profile server instead of spring in this case.
Spring comes with is own view framework implementation named spring mvc.
All of this can run perfectly on any servlet container (jetty tomcat etc...) on condition that you provide associated dependencies ofc.

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.

can spring inject EJBs into annotated fields of servlet in a Java SE webapp?

Spring has support for injecting javax.ejb.EJB annotations, much like it injects #Autowired and other jsr-220 injection annotations, thanks to the CommonAnnotationBeanPostProcessor class.
However, injection doesn't work for servlets, since the servlet isn't created by spring.
This article - Spring injects servlets too - doesn't give an example using servlets, but claims it's possible using compile-time weaving of aspects. Unfortunately, compile-time weaving is not an option for us. Is it possible to do this at runtime? It's ok to introduce a subclass to the servlet if that helps, but I want to keep EJB annotations so the servlets can still deployed in a Java EE container.
EDIT: The app will be deployed to a Java EE container in production, but I was thinking of using spring for running functional tests and for local deployment for development to take advantage of hot JSP loading in Tomcat.
You will need Java EE container like in Glassfish that supports injection of EJBs and beware that injection works on managed classes like servlets, managed beans..etc (classes that are managed by containers) so ejb injection in normal classes would require you to use lookups instead.

Resources