ciro ciro - 5 months ago 51
Java Question

spring mvc can't get ApplicationContext from bean invoked at dispatcher-servlet.xml

the purpose is to get the application context within a my bean.
I tried the utowired but does not work.

On the web I found as a solution to define the following class and get through the ApplicationContextAware interface but I always have a NullPointerException

ApplicationContextProvider.class

package it.ciro.service;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
* Created by Administrator on 01/07/2016.
*/

public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;

public static ApplicationContext getApplicationContext() {
return context;
}

@Override
public void setApplicationContext(ApplicationContext ctx) {
context = ctx;
}
}


Custom bean with null point exception (bold)

package it.ciro.service;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;
import java.util.Properties;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.core.io.Resource;

/**
* Created by Administrator on 01/07/2016.
*/
@Component
public class Configuration {

static final long serialVersionUID = 02L;
private Resource resource;
ApplicationContext applicationContext;


public Resource getResource() {
buildResource();
return resource;
}

public void setResource(Resource resource) {
this.resource = resource;
}


public void buildResource() {
Map<String, String> env = System.getenv();
String extended = env.get("ENV");
if(extended == null){
extended = "";
}

String fileName = "environment" + extended + ".properties";
File file = new File(fileName);
ApplicationContextProvider ac = new ApplicationContextProvider();
applicationContext = ApplicationContextProvider.getApplicationContext();
fileName = file.getAbsolutePath();
**resource = applicationContext.getResource(fileName);**
}
}


applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/util/spring-util-3.0.xsd
">



<bean id="userDao" class="it.ciro.dao.UserDaoImpl">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="myUserDetailsService" class="it.ciro.service.MyUserDetailsService">
<property name="userDao" ref="userDao" />
</bean>

<bean id="customAuthenticationSuccessHandler" class="it.ciro.service.CustomAuthenticationSuccessHandler" />

<!-- <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="500" />
</bean>-->

<bean id="applicationContextProvider" class="it.aciro.service.ApplicationContextProvider"></bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<!-- <property name="dataSource" ref="dataSource" />-->
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="POSTGRESQL" />
<property name="databasePlatform" value="org.hibernate.dialect.PostgreSQL94Dialect" />
</bean>



<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<!--<property name="dataSource" ref="dataSource" /> -->
<!-- <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />-->

<property name="jpaDialect" ref="jpaDialect" />
</bean>

</beans>


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:spring-security.xml
classpath:dispatcher-servlet.xml
</param-value>
</context-param>

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/assets/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/favicon.ico</url-pattern>
</servlet-mapping>

<!-- <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/uploads/*</url-pattern>
</servlet-mapping>-->

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

<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<error-page>
<error-code>404</error-code>
<location>/WEB-INF/view/404.jsp</location>
</error-page>
</web-app>


my dispatcher-servlet.xml (only part where i call Configuration class)

<bean id="applicationContextProvider" class="it.ciro.service.ApplicationContextProvider" >

</bean>
<bean id="configuration" class="it.ciro.service.Configuration">
<property name="ctxProvider" value="#{applicationContextProvider}" />
</bean>

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="#{configuration.resource}" />
</bean>

Answer

You either need to make your Configuration class implement the ApplicationContextAware interface, or you need to inject the ApplicationContextProvider class into your Configuration class. You can use the autowired annotation for this.

I might also change the getApplicationContext method in ApplicationContextProvider from static (though I think it should work even if you don't).

public class Configuration(){
    @Autowired
    ApplicationContextProvider ctxProvider;

    public void buildResource() 
        // do Something with context
       ... ctxProvider.getApplicationContext();
    }
}

Frankly, I'm not seeing much value in the ApplicationContextProvider class. I'd just have configuration directly implement ApplicationContextAware.

Comments