1

Retrieve bean from context

asked 2017-02-26 21:35:09 +0800

lramellavotta gravatar image lramellavotta flag of Italy
200 1 8

Hi, I have a problem with this code. The rootContext is null...

Any ideas? Thanks

p.s. I use in this project spring 4.3.6 (with older version 3 works fine)

/Luca

private Object getBean(String classname) 
{
  HttpServletRequest servletRequest = (HttpServletRequest) Executions.getCurrent().getNativeRequest();
  ServletContext servletContext = servletRequest.getSession().getServletContext();

  WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);

   WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
   return webApplicationContext.getBean(classname);
}
delete flag offensive retag edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2017-02-28 04:22:14 +0800

cor3000 gravatar image cor3000
4332 1 7
ZK Team

My first guess is -> webApplicationContext.getBean(classname) depends on the bean id to be the same as the class name. Maybe it's safer to give your Spring beans dedicated id, or call getBean(Class<t> type) to query by type directly.

I am not sure if the convention of automatic bean names has changed between Spring versions 3 and 4, or if the visibility within the root- or webapp-context is different. I'd check a spring forum or the spring documentation for changes there.

ZK does not change the contents of the WebApplicationContext. Those are purely managed by Spring.

Robert

link publish delete flag offensive edit
1

answered 2017-02-28 12:40:54 +0800

chillworld gravatar image chillworld flag of Belgium
5322 4 9
https://github.com/chillw...

updated 2017-02-28 18:54:14 +0800

We use Spring 4 and have this helper class :

import javax.persistence.Transient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * service locator permits the decoupling of calling code from the
 * org.springframework.beans.factory.BeanFactory API
 * <p>
 * A sample config in an XML-based org.springframework.beans.factory.BeanFactory
 * look as follows :
 *
 * <pre class="code">
 * &lt;beans&gt;
 *
 * &lt;bean class=&quot;eu.mil.meat.config.ServiceLocator&quot;
 * factory-method=&quot;getInstance&quot;/&gt;
 *
 * lt;/beans&gt;
 * </pre>
 *
 * <p>
 * The attendant <code>MyClientBean</code> class implementation might then look
 * something like this:
 *
 * <pre class="code">
 * package a.b.c;
 *
 * public class MyClientBean {
 *
 * public void someBusinessMethod() {
 *
 * MyService service = ServiceLocator.getService(MyService.class); // use the
 * service object to effect the business logic... }
 * </pre>
 *
 * @author wim
 *
 */
public class ServiceLocator implements ApplicationContextAware,
        InitializingBean {

    /**
     * The instance.
     */
    private static ServiceLocator instance = new ServiceLocator();

    /**
     * Sets the instance.
     *
     * @param instance the new instance
     */
    public static void setInstance(ServiceLocator instance) {
        ServiceLocator.instance = instance;
    }
    /**
     * The Constant SERVICE_LOCATOR_WAS_NOT_PROPERLY_INITIALIZED.
     */
    private static final String SERVICE_LOCATOR_WAS_NOT_PROPERLY_INITIALIZED = "ServiceLocator was not properly initialized, initialize SpringContext";
    @Transient
    private boolean test = false;

    /**
     * Gets the bean.
     *
     * @param <T> the generic type
     * @param class1 the class1
     * @param name the name
     * @return the bean
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(final Class<T> class1, final String name) {
        return (T) getInstance().getBeanWithName(name);
    }

    /**
     * Gets the context.
     *
     * @return the context
     */
    public static ApplicationContext getContext() {
        return getInstance().getApplicationContext();
    }

    /**
     * Gets the single instance of ServiceLocator.
     *
     * @return single instance of ServiceLocator
     */
    protected static ServiceLocator getInstance() {
        return instance;
    }

    /**
     * Return a single bean of the given type or subtypes.
     *
     * @param <T> the generic type
     * @param serviceInterface type of bean to match
     * @return the matching bean instance
     */
    public static <T> T getService(final Class<T> serviceInterface) {
        LoggerFactory.getLogger(ServiceLocator.class).debug("getting Service :" + serviceInterface.getName());
        return getInstance().locateService(serviceInterface);
    }
    /**
     * The context.
     */
    private ApplicationContext context;
    /**
     * The logger.
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /* (non-Javadoc)
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        this.logger.debug("{}", "initialized");
    }

    /**
     * Gets the application context.
     *
     * @return the application context
     */
    private ApplicationContext getApplicationContext() {
        return this.context;
    }

    /**
     * Gets the bean with name.
     *
     * @param name the name
     * @return the bean with name
     */
    private Object getBeanWithName(final String name) {
        return this.getApplicationContext().getBean(name);
    }

    /**
     * Locate2.
     *
     * @param <T> the generic type
     * @param serviceInterface the service interface
     * @return the t
     */
    @SuppressWarnings({"cast"})
    <T> T locate2(final Class<T> serviceInterface) {
        if (test) {
            return null;
        }
        if (this.getApplicationContext() == null) {
            throw new IllegalStateException(
                    SERVICE_LOCATOR_WAS_NOT_PROPERLY_INITIALIZED);
        }
        return (T) BeanFactoryUtils.beanOfTypeIncludingAncestors(this.getApplicationContext(), serviceInterface);
    }

    /**
     * Locate by class name.
     *
     * @param <T> the generic type
     * @param serviceInterface the service interface
     * @return the t exception
     */
    @SuppressWarnings("unchecked")
    public <T> T locateByClassName(final Class<T> serviceInterface) {
        T result = null;
        if (this.getApplicationContext() == null) {
            throw new IllegalStateException(
                    SERVICE_LOCATOR_WAS_NOT_PROPERLY_INITIALIZED);
        }
        this.logger.debug("locate : {}", serviceInterface);
        final String[] matchingBeanNames = BeanFactoryUtils
                .beanNamesForTypeIncludingAncestors(
                        this.getApplicationContext(), serviceInterface);
        for (final String beanName : matchingBeanNames) {
            final Object bean = this.getApplicationContext().getBean(beanName);
            if (bean != null && bean.getClass().equals(serviceInterface)) {
                result = (T) bean;
            }
        }
        if (result == null) {
            throw new NoSuchBeanDefinitionException(serviceInterface.getClass()
                    .getName());
        }
        return result;
    }

    /**
     * Return a single bean of the given type or subtypes.
     *
     * @param <T> the generic type
     * @param serviceInterface type of bean to match
     * @return the matching bean instance
     */
    @SuppressWarnings("cast")
    public <T> T locateService(final Class<T> serviceInterface) {
        T result = null;
        if (this.getApplicationContext() == null) {
            throw new IllegalStateException(
                    SERVICE_LOCATOR_WAS_NOT_PROPERLY_INITIALIZED);
        }
        this.logger.debug("locate : {}", serviceInterface);
        try {
            result = (T) BeanFactoryUtils.beanOfType(
                    this.getApplicationContext(), serviceInterface);
        } catch (final NoSuchBeanDefinitionException e) {
            return this.locate2(serviceInterface);
        }
        return result;
    }

    /* (non-Javadoc)
     * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
     */
    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) {
        this.context = applicationContext;
    }

    /**
     * package private for testing purpose
     * @param test 
     */
    void setTest(boolean test) {
        this.test = test;
    }


}

And in our context :

<bean lazy-init="false" factory-method="getInstance" class="be.chillworld.service.util.ServiceLocator" id="serviceLocator"/>
link publish delete flag offensive edit

Comments

Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
2 followers

RSS

Stats

Asked: 2017-02-26 21:35:09 +0800

Seen: 39 times

Last updated: Feb 28 '17

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More