Spring Boot find beans in web application context - spring

How do we find all the beans in web application context of web application build using spring Boot. I have seen many examples to get beans from application context but not from web application context.

Auto wire application context,
#Autowired
private ApplicationContext appContext;
And access the beans,
String[] beans = appContext.getBeanDefinitionNames();
for (String bean : beans) {
System.out.println(bean);
}

Related

Is ApplicationContext automatically instantiated in Spring?

Is ApplicationContext automatically instantiated in Spring?
If I have my bean defined like this
#Component
public class Car{
...
}
and then I have my config class which tells Spring container where to look for beans through the annotation #ComponentScan
#Configuration
#ComponentScan
public class AppConfig {
...
}
Is Spring automatically creating a context loading all my beans? Or do I have to create it programmatically? If so how do I do it, with something like this?
#Configuration
#ComponentScan
public class AppConfig {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
context.getBean(Car.class);
...
}
Even doing this, there may be a problem, because every time I need the context I have to call new AnnotationConfigApplicationContext...
what is the recommended way to instantiate the context and making him available inside the whole project, maybe as a bean like inside Spring boot app where i can just autowire it.
How Spring Boot can initialize it, load all the beans and let the context available as a bean, ready to be autowired?
No, Application Context isn't automatically instantiated, if you're having a simple and basic Spring Core application. Moreover, your #Configuration class won't scan anything and won't create any beans, if you don't create your Spring Container/Context explicitly with that #Configuration class.
There are several ways of creating Application Context, but the most popular and traditional ones are:
ApplicationContext context = new ClassPathXmlApplicationContext(applicationContext.xml) - implying, that you have your container configuration in the applicationContext.xml file;
ApplicationContext context = new AnnotationConfigApplicationContext(ConfigClass.class); - implying, that your ConfigClass is the #Configuration class.
However, if you have the Spring Boot application annotated with #SpringBootApplication, then the Application Context will be automatically instantiated for you, because:
#SpringBootApplication annotation consists of:
#EnableAutoConfiguration - which enables Spring Boot’s auto-configuration mechanism;
#ComponentScan - which enable #Component scan on the package where the application is located;
#Configuration - allows to register extra beans in the context or import additional configuration classes.
and this will spin up the context for you.
You can obtain the reference to the Spring Context created by Spring Boot, by the factory method you have in your main method: SpringApplication.run(MainClass.class, args);
This returns the reference to the Application Context and you can assign it to variable like this:
ApplicationContext context = SpringApplication.run(MainClass.class, args)

Testing servlets with spring beans and embedded jetty

What is the best way to setup embedded jetty to use Spring test context for unit tests?
We are having problems testing legacy servlets which were sprinkled up with Spring beans like this:
public class MyServlet extends HttpServlet {
#Autowired
private MachineDao machineDao;
void init() {
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, this.getServletContext());
}
...
We are using embedded jetty (v9.2) to start Server with a particular servlet to test in spring test.
#ClassRule
public static TestServer server = new TestServer(MyServlet.class);
Problem is that spring test context is not accessible in jetty so processInjectionBasedOnServletContext(...) fails.
We also want to test that .jsp is rendered correctly, so using just new MyServlet() and MockHttpServletRequest & MockHttpServletResponse approach is not really a viable option.
We are using Spring 4.11 (not MVC) with java config & annotations.
Any help much appreciated!

How contexts are represented

There are 3 main interfaces for Spring Container(bean factory ,application context and web application context ).
When we use term "root/app context and web application context " then can we say that:
web application context is represented by web applicationcontext interface and servletcontext interface
while
root context is represented by beanfactory and application context interfaces.
BeanFactory vs ApplicationContext
Spring doc explains nicely the about them-
ApplicationContext interface is which enhances BeanFactory
functionality in a more framework-oriented style
You will have all functionality that a BeanFactory can do in ApplicationCotnext. Fact is ApplicationContext interface extends ListableBeanFactory interface. You will find comparative difference between them here
ApplicationContext and WebApplicationContext
ApplicationContext is the root context configuration for every web
application. But there can be multiple WebApplicationContext under
the ApplicationContext. In other words each DispatcherServlet associated with
single WebApplicationContext.
You can find more here for better understanding.
Now can we say - web application context is represented by web applicationcontext interface and servletcontext interface ?
Actually WebApplicationcontext extended ApplicationContext which is designed to work with the standard ServletContext so it's able to communicate with the container. like
public interface WebApplicationContext extends ApplicationContext {
ServletContext getServletContext();
}
And yes, root context or application context is represented by ApplicationContext interface. And you know the difference of BeanFactory with this.

Integrating Spring XML beans from external jar into a CDI application

I have a new CDI Java EE application running on WebSphere. Now I want to use an existing module (.jar) in my CDI project, however the existing module uses Spring with Spring annotations and an Spring XML configuration file with additional bean definitions in it. Normally I would just import the Spring XML in my project, but in the CDI application this will not work.
I tried to load the Spring XML using JBoss Seam, like so:
#Produces
#SpringContext
#Configuration(locations = "classpath*:external-spring--context.xml")
ApplicationContext context;
But the context is null? I cannot realy find good examples on how to do this, help is much appreciated :)
I solved it by adding an CDI producer that will create the Spring context using the spring XML file:
public class SpringBeansFactory {
#Inject
ApplicationContext context;
#Produces
public BusinesService getBusinessService() {
return context.getBean(BusinesService.class);
}
}
class SpringContextFactory {
#Produces
public ApplicationContext getApplicationContext() {
return new ClassPathXmlApplicationContext("classpath:spring-context.xml");
}
}

Spring bean initialized on web app starts up

This is probably due to my ignorance of the Spring framewok but i am building a JSF+Facelets+Spring web app, i have a bean that whose init method i want to get called at the time the application is started. My problem is getting the bean initialized. I can reference the bean on a page, and when I go to the page, the bean is initialized, and works as directed; what I would like instead is for the bean to be initialized when the application is started
What is the way to get a Spring bean initialized on web app starts up
Your question is more Spring-targeted than JSF-targeted. I know the solution for JSF, but I don't think that this suits a Spring bean. I googled a second and found this topic at the Spring forum which may be of use for you. It describes/links several different approaches: http://forum.springsource.org/archive/index.php/t-21982.html
All the code that you want to handle immediately after an webapp is initialized can be done in a class that implements ServletContextListener as
#WebListener
public class ApplicationListener implements ServletContextListener {...}
and you can create spring application context like
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
// of course, an ApplicationContext is just a BeanFactory
BeanFactory factory = context;
and get the bean you are interested in and go on.

Resources