ContextSingletonBeanFactoryLocator alternative in spring 5
Asked Answered
S

2

8

We were using 4.2.x version of spring and we are using ContextSingletonBeanFactoryLocator to load bean like below

BeanFactoryLocator bfLocator = ContextSingletonBeanFactoryLocator.getInstance("classpath:customBeanRefFactory.xml");
BeanFactoryReference ref = bfLocator.useBeanFactory("sharedApplicationContext");
BeanFactory beanFactory = ref.getFactory();
((AbstractApplicationContext) beanFactory).getBeanFactory().setBeanClassLoader(CustomSpringBeanFactory.class.getClassLoader());
return (ApplicationContext) beanFactory

We are planning to upgrade to spring 5.0.x and figured out ContextSingletonBeanFactoryLocator and classes like BeanFactoryLocator and BeanFactoryReference are removed from spring 5.0 release.

So what are the suggested alternatives to get application context?

@Configuration
@ImportResource("classpath:ourxml")
public class OurApplicationConfiguration {

}


public class OurAppicationFactoryProvider {

    ApplicationContext context;

    public ApplicationContext getApplicationContext() {
        if (context == null) {
            synchronized (this) {
                if (context == null) {
                    context = new AnnotationConfigApplicationContext(OurApplicationConfiguration.class);
                }
            }
        }
        return context;
    }
}

Is this even right approach or there are other alternatives?

Skindive answered 25/1, 2018 at 6:0 Comment(4)
Basically the fact that you are getting the ApplicationContext is already a flaw, in an application you shouldn't need it (assuming that Spring is creating the context). Your "solution" makes it even worse as that will load the context twice (assuming Spring is also instantiating the context).Unscratched
We have few legacy bean which are not annotated by spring annotation. So we were using application context to get themSkindive
Legacy beans not annotated but get them through the context? If you can get them through the context you can inject them... If your only task is that you can just @Autowire the ApplicationContext into your OurAppicationFactoryProvider. Don't create a new one (in the worst case you also have class loader issues and you load the application numerous times).Unscratched
I will try that.Skindive
K
6

In my legacy application which was based on BeanFactoryLocator/beanRefContext.xml mechanism mentioned at https://jira.spring.io/browse/SPR-15154, I added a Singleton class to create application context and use that context. My code is

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public enum SpringContextUtil {
    INSTANCE;
    ApplicationContext context;

    public ApplicationContext getApplicationContext() {
        if (context == null)
            context = new ClassPathXmlApplicationContext("classpath*:beanRefContext.xml");
        return context;
    }

}

and I replaced

    final BeanFactoryReference ref = ContextSingletonBeanFactoryLocator.getInstance().useBeanFactory(contextKey);
    AbstractApplicationContext context = ((AbstractApplicationContext) ref.getFactory());

by

AbstractApplicationContext context = (AbstractApplicationContext)SpringContextUtil.INSTANCE.getApplicationContext().getBean(contextKey);

Hopefull that would help someone in my shoes.

The solution might not be applicable to all situation.

Keller answered 12/9, 2018 at 17:43 Comment(0)
A
0

In a similar situation we reintroduced the locator mechanism directly into our code.

Aubervilliers answered 24/11, 2021 at 10:8 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Arable

© 2022 - 2024 — McMap. All rights reserved.