Uses of Spring’s ApplicationContext while using reflection

Uses of ApplicationContext while using reflection

Generally speaking, Spring’s ApplicationContext is not advised to be used in the project business logic code as it binds the code to Spring API. But, if your application is using Spring API a lot then it is okay to use the ApplicationContext interface to get the beans created in the Spring Application.

I have found one rare use case of this ApplicationContext being used in a static way inside a class whose instance is obtained using reflection.

So, in this post, I will share my experience of using the following piece of code that I found quite useful. The following Java Code helps you to access the beans created in the application in a static way.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class ApplicationContextAccessor {

    private static ApplicationContextAccessor instance;

    @Autowired
    private ApplicationContext applicationContext;

    public static  T getBean(Class clazz) {
        return instance.applicationContext.getBean(clazz);
    }

    @PostConstruct
    private void registerInstance() {
        instance = this;
    }
}

Using this class, we can utilize the code that has been modeled using the dependency injection. If dependencies are not injected by the underlying DI container the objects can not be directly used in the classes whose instances are obtained using reflection.

For example say, you have a service layer developed using the DI. The code will work fine when you use the service layer interfaces @Autowired in the classes that you intend to use. For that the class in which you want to use the service layer has to be marked as @Component. If you mark the class as @Component the DI container will take care of the object instantiation and it will manage everything for you.

But, at times you may be interested in using such a service layer in classes whose instances are obtained using Class.forName(..) approach. Then the newly created object instance is not known to the DI contaier and the fields marked with @Autowired will be null, in which case the whole service layer classes and their injections will also be null. As a result we will get NullPointerException.

To avoid such exceptions, the above Accessor class can be used in the following way…

YourServiceLayerInterface serviceInstance = ApplicationContextAccessor.getBean(YourServiceLayerInterface.class); 

Now, since you are getting the service layer instance from the DI container, objects won’t be null.

Drawbacks:

The possible drawbacks when an interface is used as the argument to the getBean method, there can’t be multiple implementations of that interface. If there are multiple implementations you will get RuntimeException from Spring that the instance could not be produced.

If only single implementation has to be there to be used an an argument that defeats the purpose of using interfaces. To solve this issue, one can use the direct implementation classes as the argument to the getBean method. But, actually it becomes hard coding the concrete classes in the application.

Hope you found this article useful and thank you for reading.

Rajasekhar
Helical IT Solutions

About multiple contexts of the Spring MVC Framework

Spring MVC and Multiple Spring Contexts

 

Spring framework is one of the widely used frameworks in Enterprise Java World. Using Spirng MVC requires a proper understanding of ‘Contexts’ of the framework.

Spring has provision for defining multiple contexts in parent/child hierarchy. Spring manages beans that belong to different contexts. The org.springframework.context.ApplicationContext is consisered as the root context or parent context for all the other contexts.

From the official documentation:

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.

Again there is one more context called WebApplicationContext in Spring MVC, which is a child context. The FrameworkServlet of the spring framework i.e. DispatcherServlet will have this web context.

Again from the official docs:

In the Web MVC framework, each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext. These inherited beans can be overridden in the servlet-specific scope, and you can define new scope-specific beans local to a given Servlet instance.

The ApplicationContext related beans are loaded using one of the two following ways.

In web.xml we can have configuration for the org.springframework.web.context.ContextLoaderListener class, which is a servlet context listener in the following way. This listener will get invoked when a web app gets deployed on the server.

ContextLoaderListener configuration:


<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/application-context.xml</param-value>
</context-param>

This listener looks for a context-param named contextConfigLocation in the web.xml. If it finds one, then the xml meta data file will be scanned for the beans that belong to the root application context. If it doesn’t find any, then the listener will look for a file named applicationContext.xml in the class path for the configuration meta data.

Similarly the DispatcherServlet, which is configured in the web.xml will look for an init-param named contextConfigLocation in the servlet definition as shown below.

DispatcherServlet configuration:


<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

If the init-param is not configured, then a file named dispatcher-servlet.xml will be searched for in the class path. Tha file name being searched for is made up of the servlet name – in our case ‘dispatcher’ – and a string ‘-servlet.xml’ as suffix.

Note:
The child context i.e. the MVC context will have access to the beans in the parent or root context. But not vice versa.

So, in both the cases i.e. the ContextLoaderListener or in case of DispatcherServlet if the parameters are not found in the web.xml and the corresponding files applicationContext.xml or YOUR SERVLET NAME-servlet.xml are not found in the class path then a FileNotFoundException will be thrown and the application won’t start up.

Usually the model classes and other beans that belong to the entire application are configured as beans in the applicationContext.xml. And the classes annotated with @Controller and the beans that are related to the MVC layer are configured in the DispatcherServlet configuration file.

Most of the tutorials on web have Spring MVC configuration with a single file included in both the parent context as well as in the child context because of lack of understanding of how Spring works. Due to this all the beans configured in the corresponding xml file will be instantiated twice including any of those beans defined for connection pooling, in which case connection pooling will also be a problem.

If we have only one file with spring beans configuration meta data, then we can configure only that xml file in DispatcherServlet‘s web context, which is the only mandatory context for an MVC web application, in which case we can exclude the configuration for the servlet context listener ContextLoaderListener in the web.xml.

So, whenever one considers using Spring MVC the understanding of these contexts is a must. Hope this article helped you and wish you happy coding.

–Rajasekhar
Java BI Developer
Helical IT Solutions

Spring Security

Spring Security Spring provides a configurable framework for implementing authentication and authorization for an application. The security framework provides ways to login and logout from an application. It also provides authentication at view level and method level. It can also provide you with the login page. Following are the provided by spring security framework • Provide capabilities for login and logout.
• Control access to a link based on the role of the user.
• Provide the ability to hide certain portion of the page if user does not have appropriate privileges.
• Link to database or LDAP for authentication.
To implements spring security we need three jar mainly spring-security-core, spring-security-web and spring-security-config download these jar and set in application class path.

\src\main\webapp\WEB-INF\web.xml

We need to add security configuration and spring-security filter chain in web.xml to tell the container about security setting and configuration.

<web-app id=“WebApp_ID” version=“2.4”

xmlns=“http://java.sun.com/xml/ns/j2ee” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://java.sun.com/xml/ns/j2ee

    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd”>

<display-name>Helical Project</display-name>

<!– Spring MVC –>

<servlet>

<servlet-name>mvc-dispatcher</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>mvc-dispatcher</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

/WEB-INF/mvc-dispatcher-servlet.xml,

/WEB-INF/spring-security.xml

</param-value>

</context-param>

<!– Spring Security –>

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

<filter-mapping>

<filter-name>springSecurityFilterChain</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

</web-app>

\src\main\webapp\WEB-INF\mvc-dispatcher-servlet.xml

Here is simple spring-dispatcher, we have added view resolver and component scan attribute to scan application controller

<?xml version=“1.0” encoding=“UTF-8”?>

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:context=“http://www.springframework.org/schema/context”

xmlns:mvc=“http://www.springframework.org/schema/mvc”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xmlns:util=“http://www.springframework.org/schema/util”

xsi:schemaLocation=

            http://www.springframework.org/schema/mvc

            http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 

            http://www.springframework.org/schema/beans      

            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 

            http://www.springframework.org/schema/context  

            http://www.springframework.org/schema/context/spring-context-3.0.xsd

            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd”>

<context:annotation-config />

<context:component-scan base-package=“com.helical.scrunch.controller” />

<bean class=“org.springframework.web.servlet.view.InternalResourceViewResolver”>

<property name=“prefix”>

<value>/WEB-INF/jsp/</value>

</property>

<property name=“suffix”>

<value>.jsp</value>

</property>

</bean>

</beans>

\src\main\webapp\WEB-INF\spring-security.xml

This is called spring-security configuration file to specify login details and security url’s to check for login.

<beans:beans xmlns=“http://www.springframework.org/schema/security”

xmlns:beans=“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-3.0.xsd

       http://www.springframework.org/schema/security

       http://www.springframework.org/schema/security/spring-security-3.2.xsd”>

 

<!– enable use-expressions –>

<http auto-config=“true” use-expressions=“true”>

<intercept-url pattern=“/admin**” access=“ROLE_ADMIN” />

</http>

 

<authentication-manager>

<authentication-provider>

<user-service>

<user name=”test” password=”test” authorities=”ROLE_ADMIN”>

<password-encoder hash=“bcrypt” />

</user-service>

</authentication-provider>

</authentication-manager>

</beans:beans>


\src\main\java\com\helical\scrunch\controller\MainController.java

package com.helical.scrunch.controller;

@Controller

public class MainController {

@RequestMapping(value = “/admin**”, method = RequestMethod.GET)

public ModelAndView adminPage() {

ModelAndView model = new ModelAndView();

model.addObject(“title”, “Redirected to Admin Page”);

model.addObject(“message”, “This page is for ROLE_ADMIN only!”);

model.setViewName(“admin”);

return model;

}

}

Here is admin.jsp page which will display after successful login

\src\main\webapp\WEB-INF\jsp\admin.jsp

<[email protected] prefix=“c” uri=“http://java.sun.com/jsp/jstl/core”%>

<[email protected] session=“true”%>

<html>

<body>

<h1>Title : ${title}</h1>

<h1>Message : ${message}</h1>

</html>

</body>

Spring provides the build in login page for us or you can develop your own custom login page.

If everything is correct you can see the login page on http://localhost:8080/your-project-name/admin

 

Reading multiple properties files in spring 3 web MVC

    Reading multiple properties files in spring 3 web MVC

Spring allows us to externalize string literals in its context configuration files into external properties files, in order to separate application specific settings from framework specific configuration. Spring will read all the properties files declared by PropertyPlaceholderConfigurer bean to resolve the placeholders at application’s start up time.

Simple Example

Declare a PropertyPlaceholderConfigurer bean in spring’s application context as follows:
That tells spring to load the properties file name project.properties in the class path. An exception will be thrown if spring could not find specified property file.
The project.properties file should contain the name and value pair for example
Name = xyz
Filepath = C:/Test/Setting.xml
Host = localhost
User = testuser

By default spring look for the properties files in the application directory. So if we specify

Then it will find project.properties file under WEB-INF directory of the application in case of spring MVC application.
We can use prefix classpath: to tell spring load properties file in the application’s classpath. For example:

In the case of spring application the project.properties file should be present in WEB/INF/classes directory or in source directory src in eclipse IDE.

Use the prefix file:/// or file: to load property file from file system.

Spring context load the project.properties file from D:/Applicatin/Config else throws the exception if file is not present in the specified path.
Loading multiple properties files
Spring allows us to specify multiple properties files for the PropertyPlaceholderConfigurer as follows

classpath:/processor.properties
classpath:/datasource.properties

</property

We can add as many as properties file in list as shown above. Spring context will load all the properties files specified in list as shown above at the application start up time.

Loading Properties files values in spring controller
Suppose you have properties file as follows
Name = xyz
Filepath = C:/Test/Setting.xml
Host = localhost
User = testuser

We can use the variable read from properties files in spring controller by declaring @Component annotation in controller class for example:
@Controller
@Component
public class Controller{
@Value(“${Name}”)
String Name;
@Value(“${Filepath }”)
String Filepath;
@Value(“${Host }”)
String Host;
@Value(“${User }”)
String User;
}

The value of properties file automatic assign to declared variable by spring framework we can use these variables inside the application.

Muqtar Ahmed
Helical IT Solutions