I am new to guice and my background is JakartaEE. So I have a conceptual question about the binding of beans.
As far as I understand, in Guice I have to implement my AbstractModule where I bind my concrete implementations. Than I am able to inject those classes into other classes. Which means, I need to programmatically bind everything in my Module.
In JakaratEE we have the CDI Container which automatically scans all jar files for CDI beans and binds them automatically. This means I can add an external .jar file with CDI beans or Obsever Beans that automatically can react on specific CDI Events of my main application, without the need to register a ActionHandler programmatically in my main application. I can just fire the CDI event and all Listeners in any existing Jar file will be triggered by the Jakarta CDI Container.
It looks to me that Guice is not providing such a mechanism? Or is there a similar way that I can extend the main application without the need to compile it with the specific extension?
Related
I am a new user of Spring framework. I am facing some confusion in understanding the difference between core spring framework and spring boot. As far as I understand, Spring boot is a framework which performs the initial setup automatically (like Setting up Maven dependencies and downloading the jar files) and comes with an embedded Tomcat server which makes it ready to deploy in just one click., Whereas, Spring MVC requires manual setup. All the tutorials that I watched for core spring show bean configuration using bean factory which configures the beans using a .XML file. In Spring boot, this bean configuration file is absent. My question is, what is the use of this bean configuration file? I did not find any legitimate use of this file in making a REST service with spring. I didn't see any use of the Application Context, Bean Factory in creating web application. Can someone point out how can bean factory be used in Spring web apps? Is there any fundamental difference between core spring and spring boot other than the additional components?
The Spring application context is essentially the "pool" of beans (service objects, which include controllers, converters, data-access objects, and so on) and related information that define an application; I recommend the reference introduction. In theory, you can get complicated with the context setup and have hierarchical organization and such, but in most real-world cases you just have a single plain context.
Inside this context you need to install all of the beans that provide the logic for your application. There are several possible ways to do this, but the two main ways are by providing XML files with have directives like bean (define an individual bean) or component-scan (automatically search for classes with certain annotations, including #Controller) and by using Java classes annotated with #Configuration, which can use annotations and #Bean methods.
The XML style is generally older, and newer applications mostly use Java configuration, but both provide entries that are collected into the context, and you can use both simultaneously. However, in any application, you have to provide some way of getting the registration started, and you will typically have one "root" XML file or configuration class that then imports other XML files and/or configuration classes. In a legacy web.xml-based application, you specify this in your servlet configuration file.
Spring Boot is, as you said, essentially a collection of ready-to-go configuration classes along with a mechanism for automatically detecting configurations and activating them. Even this requires a configuration root, though! This is the #EnableAutoConfiguration instruction, frequently used through its composite #SpringBootApplication. The application context and configuration mechanisms work normally once Boot finds them and pulls them in. Spring knows where to get started because you give it an explicit instruction to build a context starting with that entry point, usually with SpringApplication.run(MyApplication.class, args).
The embedded-server configuration just happens to be a particular set of configuration that is really useful and comes with one of the Boot starter packages. There's nothing there that you couldn't do in a non-Boot application.
I'm trying to add a Interceptor in a EJB at runtime programmatically via CDI extensions.
This EJB exposes a Remote interface for remote calls. But I'm trying to add this Interceptor in the implementation class of this EJB adding the #Interceptors annontation like in this other SO question (CDI Extensions - Add Interceptors in ProcessAnnotatedType phase)
I think the CDI Extension only executes after the EJB are already registered because the Interceptor is never called.
But, for test purpose I have successfully register and execute an Interceptor programmatically in a simple CDI Bean.
The problem is when I'm try to register in a EJB.
Am I missing something?
Edit:
I'm using Wildfly 8
I think the key problem here is the difference between #Interceptors (EJB ones) and #Interceptor (CDI ones). CDI does not govern EJB container hence adding the EJB annotation (#Interceptors) in CDI extension won't necessarrily kick EJB logic into effect - EJB container might have started at that moment and it won't know of the annotation. Furthermore the CDI extension would add this annotation to the AnnotatedType which is a structure EJB probably won't make use of. On the other hand, all this really depends on the application server as it is responsible for CDI/EJB integration hence as a "bonus" the behavior might differ between AS.
CDI extension is something which allows you to hook into CDI bootstrap lifecycle, therefore you are able to use/enable/add CDI interceptors. I would try going that way instead. BTW even the SO question you referred to speaks of beans.xml/#Priority for enablement which means it uses CDI interceptors and not EJB ones.
Also, an EJB bean should automatically become CDI bean therefore you can attach CDI interceptor to it without changing the bean itself.
My question is: why do I need to create AbstractModule when doing JavaSE application and ServletModule while creating application that is deployed on some kind of servlet container like jetty or tomcat? What are the differences between them?
I need to integrate Jersey with Guice. Is it necessary to register presence of Guice for Jersey to use it somehow? Can't I just enable injections and do them everywhere I want (normal classes, filters, handlers, services, DAOs etc.)? And why can't I just configure guice like in JavaSE application, but instead need to use ServletModule?
As far as I see on web, there are many examples of using HK2 services by Guice and vice versa, so I can consider it as important? (necessary?)
Thanks
An AbstractModule is the basic building block of the bootstrap (configuration) phase of Guice. You always need one or more of that. On the other hand a ServletModule is an specialization which does some configuration for you given the fact that it is running in a servlet container.
From the Guice documentation:
This module sets up the request and session scopes, and provides a
place to configure your filters and servlets from.
About the Guice-Jersey integration you certainly need to set it up. It won't work out of the blue. Guice, as any other dependency injection framework, works when it has the control of building your objects. When in doubt ask yourself who creates the object.
With Jersey, and JAX-RS in general, who creates the objects? Not you, you just define them. The container creates them. The JAX-RS runtime. In your case, the Jersey runtime. And Jersey uses internally the HK2 dependency injection framework. So you need to bridge both those frameworks in order to inject a JAX-RS class you have defined with some Guice resources. Or the other way around! That is the reason why there is a HK2-guice bridge. So Jersey would build your objects using HK2 and HK2 will look up your resources also on Guice thanks to the bridge.
A simple example. I use this code to initialize a REST API where I want to inject Guice resources.
#ApplicationPath("api")
public class ApiRest extends ResourceConfig {
private static final Logger log = LoggerFactory.getLogger(ApiRest.class);
#Inject
public ApiRest(ServiceLocator serviceLocator, ServletContext servletContext) {
log.debug("Inicialitzant Jersey.");
packages("net.sargue.app.api");
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
Injector injector = (Injector) servletContext.getAttribute(Injector.class.getName());
if (injector == null)
throw new RuntimeException("Guice Injector not found");
guiceBridge.bridgeGuiceInjector(injector);
}
}
Please note that the above example needs the ServletModule registered as it pulls the Guice injector from the ServletContext. Or you can just add the injector to the ServletContext somewhere else. Or just create the injector when initializing the REST API, it depends on your preferences and the application.
I am studying for the Spring Core certification and I have following doubt about this question:
What is meant by “container” and how do you create one?
I know that the Spring container is at the core of the Spring Framework. The container will create the objects, wire them together, configure them, and manage their complete lifecycle from creation till destruction. The Spring container uses dependency injection (DI) to manage the components that make up an application. These objects are called Spring Beans which we will discuss in next chapter.
And I know that there exist 2 containers:
Spring BeanFactory Container: This is the simplest container providing basic support for DI and defined by the org.springframework.beans.factory.BeanFactory interface. The BeanFactory and related interfaces, such as BeanFactoryAware, InitializingBean, DisposableBean, are still present in Spring for the purposes of backward compatibility with the large number of third-party frameworks that integrate with Spring.
Spring ApplicationContext Container: This container adds more enterprise-specific functionality such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners. This container is defined by the org.springframework.context.ApplicationContext interface.
Ok...this is pretty clear for me but what is the correct answer about How to create a container?
I think that it is automatically created by the Spring when it reads the configuration class or the XML configuration file.
Or not? What am I missing?
In short, "The Container" is a Spring instance in charge of managing the lifecycle of your beans.
To create one, basically, you should do something like
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
Remember replacing /application-context.xml by the file where you define your own Spring beans.
Take a look at http://www.springbyexample.org/examples/intro-to-ioc-creating-a-spring-application.html
You could also substitute the xml by a configuration class. On that case you should have something like this:
#Configuration
public class Myconfig{
#Bean
public MyBean myBean(){
return new MyBean();
}
}
For this, take a look at http://www.tutorialspoint.com/spring/spring_java_based_configuration.htm
I have application consisting two web apps and EAR level jar files.
One web app (Lets say SPApp) is built using Spring and another using Struts (STApp).
I want to share the Aspect class SystemArchitecture of SPApp as defined here spring aop
6.2.3.3. Sharing common pointcut definitions
in STApp.
I have added SystemArchitecture class in EAR level jar file and gets invoked from SPApp but doesn't execute when STApp is accessed.
So then I moved the aspect class SystemArchitecture inside STApp and surprisingly it worked.
I am not sure what is going wrong when I place SystemArchitecture in EAR level lib.
Please help.
Thanks,
Hanumant
Spring AOP will not work outside spring. The Spring implementation of AOP is based on dynamic proxying where the spring bean factory will proxy advised classes to inject your pointcuts. What you are after is what's called "load time weaving" in where a java agent is used to intercept the ClassLoader and decorate advised classes when they are loaded. This is an AspectJ functionality, not a Spring AOP. Read more here: http://www.eclipse.org/aspectj/doc/released/devguide/ltw.html
Spring and AspectJ can play together as well, but it's limited to spring driven applications: http://static.springsource.org/spring/docs/3.0.0.RC2/spring-framework-reference/html/ch07s08.html
Still, if you want "true" AOP, independant of Spring then you need to go load-time weaving and AspectJ.
EDIT: may have misread your question. You say it works in your struts app only when you put your advise class in the app itself. From that I read that your Struts app is Spring driven as well. It's hard to give an answer without knowing your config. Specifically, web.xml (both), application.xml and your spring configs.