This question already has answers here:
application context. What is this?
(4 answers)
What is Application context and bean factory in spring framework [duplicate]
(1 answer)
Closed 3 years ago.
I have a Spring Boot app and it's running with Spring Data, MySQL, Spring Security and MVC. The app is running for me just as fine.
However, I keep hearing about ApplicationContext a lot and I was wondering when do I need to use it and would like to know what it does. Can someone give me an example and an overview of ApplicationContext and its use?
ApplicationContext is a core interface that Spring framework built on. If you're building a Spring application, you're already using the ApplicationContext. You can have great insight about this from Spring Framework Reference Documentation. As per this document, Spring framework consists with these modules;
The Context (spring-context) module builds on the solid base provided
by the Core and Beans modules: it is a means to access objects in a
framework-style manner that is similar to a JNDI registry. The Context
module inherits its features from the Beans module and adds support
for internationalization (using, for example, resource bundles), event
propagation, resource loading, and the transparent creation of
contexts by, for example, a Servlet container. The Context module also
supports Java EE features such as EJB, JMX, and basic remoting. The
ApplicationContext interface is the focal point of the Context module.
spring-context-support provides support for integrating common
third-party libraries into a Spring application context, in particular
for caching (EhCache, JCache) and scheduling (CommonJ, Quartz).
Spring ApplicationContext also inherits BeanFactory super-interface. So technically ApplicationContext is capable of doing all the things, BeanFactory interface is capable and much more. BeanFactory interface along with ApplicationContext provide the backbone of the Spring IoC container (Core container). Which is Bean management for your application.
The interface org.springframework.context.ApplicationContext
represents the Spring IoC container and is responsible for
instantiating, configuring, and assembling the aforementioned beans.
The container gets its instructions on what objects to instantiate,
configure, and assemble by reading configuration metadata. The
configuration metadata is represented in XML, Java annotations, or
Java code. It allows you to express the objects that compose your
application and the rich interdependencies between such objects.
ApplicationContext uses eager loading mechanism. So, every bean declared in your application, initialize right away after the application started and after, this ApplicationContext scope is pretty much read-only.
Initiate a Spring IoC container with custom bean definitions is pretty much staright forward.
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"daos.xml"});
Following file shows this daos.xml file content;
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao"
class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for data access objects go here -->
</beans>
After that you can access the beans define in the .xml like this;
JpaItemDao obj = (JpaItemDao) factory.getBean("itemDao");
These instances are now being initialized and managed by the ApplicationContext. But most users prefer to use #Bean annotation define beans to do the binding and #Autowired annotation to do the dependency injection. So, no need to manually feed a bean .xml to custom initialized ApplicationContext.
#Configuration
class SampleConfig {
#Bean
public JpaItemDao getJpaItemDao() {
return new JpaItemDao();
}
}
and inject in;
#Component
class SampleComponent {
#Autowired
private JpaItemDao itemDao;
public void doSomething() {
itemDao.save(); // Just an example.
}
}
Besided the bean management, ApplicationContext does some other important thing in the Spring core container. As per ApplicationContect javadoc, they are;
Bean factory methods for accessing application components. Inherited from ListableBeanFactory.
The ability to load file resources in a generic fashion. Inherited from the ResourceLoader interface.
The ability to publish events to registered listeners. Inherited from the ApplicationEventPublisher interface.
The ability to resolve messages, supporting internationalization. Inherited from the MessageSource interface.
Inheritance from a parent context. Definitions in a descendant context will always take priority. This means, for example, that a
single parent context can be used by an entire web application, while
each servlet has its own child context that is independent of that of
any other servlet.
Also, checkout the sub-interfaces of ApplicationContext that specifically designed for work on different use cases like WebApplicationContext.
ApplicationContext is a core concept (arguably the most important one) of spring used also in spring boot of course but and ideally hidden from the programmers in both cases, meaning that the programmer should not directly interact with it in a business code of the application.
Technically its an interface that has many implementations, the relevant one is picked depending on in which environment you're running and how do you configure the application.
So does it do? Its a class that basically is a registry of all the beans that spring has loaded. In general, starting up the spring mean finding the beans to load and putting them in the application context (this is relevant for singletons only, prototype-scopes beans are not stored in the ApplicationContext).
Why does spring need it?
For many reasons, to name a few:
To manage lifecyle of the beans (when the application shuts down, all beans that have a destroy method should be called)
To execute a proper injection. When some class A depends on class B spring should inject class B into class A. So by the time of creating the class A, class B should already be created, right? So spring goes like this:
Creates B
Puts B into application context (registry)
Creates A
For injection goals: gets B from the application context and injects into A
// an illustration for the second bullet
class B {}
class A {
#Autowired
B b;
}
Now there are other things implemented technically in application context:
Events
Resource Loading
Inheritance of application contexts (advanced stuff, actually)
However now you have an overview of what it is.
Spring boot application encapsulates the application context but you can still access it from many places:
in the main method when the application starts it returns an application context]
you can inject it into configuration if you really need
its also possible to inject the application context into the business bean, although we shouldn't really do so.
In simple words:
Spring is popular for dependency Injection.
So all the bean definitions(Objects) will be created by the spring and maintained in the container. So all the bean life cycle will be taken care by spring container.
So ApplicationContext is a interface It has different implementations will be there to initialize the spring container.
So ApplicationContext is the reference to Spring Container.
Some popular implementations are:
AnnotationConfigWebApplicationContext,
ClassPathXmlApplicationContext,
FileSystemXmlApplicationContext,
XmlWebApplicationContext.
Reference: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html
Can instances created by the Blueprint <bean> tag be auto injected with service references specified using the OSGi Declarative Services mechanism?
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
#Component(service={})
public class DatabaseThing{
#Reference
public void setDataSource(DataSource ds){
...
}
If I instantiate via immediate=true in the #Component then my DataSource OSGi service is injected. If I create the instance via blueprint <bean class="DatabaseThing"> then no auto-injection occurs.
I've had a look at the Aries source, and it seems that the service injection is specific to org.apache.aries.blueprint.container.ServiceRecipe and isn't part of ...BeanRecipe which is used for <bean> style instantiation.
That does not work. The DS annotations are processed by bnd and result in a DS xml file that will then be evaluated by felix scr at runtime. In this case the full lifecycle of the object is controller by scr.
If you additionally declare a blueprint bean for the same class then it will be a separate instance. Blueprint can the inject services and beans into this instance but it is completely disconnected from DS.
If your main concern is to use annoations for blueprint injections then I recommend the blueprint-maven-plugin. It allows to use CDI and Java EE annotations in your code. These are translated to a blueprint.xml at build time. So the result is similar to DS but powered by blueprint.
I have an application using Spring Integration where I have multiple handlers (strategies) for some service gateway methods, and I want the deployment launcher to be able to select which specific handlers are loaded. Since component scanning will pick up all of the handlers indiscriminately, I prefer to explicitly declare JavaConfig #Beans for them.
This works fine for the service objects themselves, but I can't find a way to load the service interface itself in Java without #IntegrationComponentScan. My current workaround is to include a "one-liner" XML file with an <int-gateway> tag and #ImportResource it, but I'd really prefer a more direct solution.
Is there any straightforward way in JavaConfig to tell Spring Integration to create a proxy service interface for a specific class?
GatewayProxyFactoryBean is for you.
This class is used to populate bean definition from <int:gateway> tag and from MessagingGateway annotation.
So, you can do like this:
#Bean
public GatewayProxyFactoryBean myGateway() {
GatewayProxyFactoryBean factoryBean = new GatewayProxyFactoryBean(YourServiceInterface.class);
factoryBean.setDefaultRequestChannel(gatewayRequestChannel());
return factoryBean;
}
I'm using spring 3.1. And I need to make a html file in my web root at spring startUp.
Of course I know JSP makes a html, but it's about request-response. I need to create a html on the startup.
And.. I hope my job is possible in pure Spring framework.
I know of Quartz.. but I don't want to use quartz. Because I'm afraid that adopting Quartz may need many changes in my Spring config.
You can create a bean that implements ApplicationListener. An ApplicationListener listens to events published by the context.
The ApplicationContext publishes certain types of events when loading
the beans. For example, a ContextStartedEvent is published when the
context is started and ContextStoppedEvent is published when the
context is stopped.
Using an application listener allows you to execute some tasks when the application is first started or the context is refreshed.
Here is an example of a basic ApplicationListener from one of my projects:
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
//Generate html file here, this method is called when event happens
}
}
And its configuration:
<!-- Fired when different application events occur such as context refresh or startup -->
<bean id="myListener" class="fully.qualified.MyApplicationListener" />
I'm new to OSGI and currently trying to use it to create modular web application. Web application itself is created using Vaadin 6.
I following this WIKI article at Vaadin web site: Creating Modular Vaadin application with OSGI
Steps I've did so far:
- created OSGI bundle for module service (simple service which tracks other osgi modules a.k.a. plugins) and deployed it to jboss.
- created vaadin application, just a stub.
OSGI service supposed to be injected to Servlet class, like:
#WebServlet(urlPatterns="/*")
public static class Servlet extends AbstractApplicationServlet {
#Resource(mappedName="vaadin-moduleService")
ModuleService moduleService;
#Override
protected Class<? extends Application> getApplicationClass() {
return ModuleDemoApp.class;
}
#Override
protected Application getNewApplication(HttpServletRequest request) throws ServletException {
return new ModuleDemoApp(moduleService);
}
}
Now the question - how this service can be injected here? Currently I'm just getting NULL pointer, so DI doesn't work. From article referred above:
Note, that the servlet has a moduleService field annotated with the
#Resource annotation. One of the interesting features of GlassFish 3
is that it is possible to inject references to OSGi services into all
container managed Java beans, even though they are not actually
running in the OSGi container themselves. Thus, in this case, GlassFish
will find the module service we define in the previous section and inject it.
According to this Glassfish will do all the magic internally and automatically. Anyone aware of how to get it done using JBoss7?
Unfortunately didn't find any good (for newbie) explanation on how anything running inside of OSGI container can be referenced outside of it... Suppose that converting of the web application itself to OSGI bundle is not required to acomplish what I need. Is this true?
Thanks a lot.
The documentation states that the JavaEE component can get the BundleContext injected as a #Resource. If that works, then you can track your module service through a ServiceTracker.
I saw another example of using Vaadin together with OSGi here.