Spring add external Spring context at run time

We have a home page that contains several components (widgets), like a portal containing portlets. Advertising banks from other teams will be delivered to some of these widgets, and some of them will need to manage some beans using Spring. One solution might be to import spring contexts using the import statement with the wildcard i (for example, import all contexts into the classpath corresponding to context-widget - *. Xml).

However, I prefer a more software solution, where I check each widget, what context they need to load (from the class path). I did not find a single blog or one that explains this, but I found some forum posts that explain that this will be a parent-child context, and it will only be one-way; unfortunately in my case it has to be bidirectional.

So, after some viewing in the API, I managed to come up with something working, but I'm not sure if this is a good solution, or there are some pitfalls that I did not think about. Perhaps there is another (better) solution for this scenario?

public class WidgetManager implements ApplicationContextAware { @Autowired private WidgetService widgetService; @Override public void setApplicationContext(ApplicationContext parentApplicationContext) throws BeansException { //I do need the parent context to have finished initializing beans List<WidgetTO> widgets = widgetService.findAllWidgets(); List<String> contexts = newArrayListWithCapacity(widgets.size()); for (WidgetTO widget : widgets) { if (isNotBlank(widget.getSpringContext())) { contexts.add(widget.getSpringContext()); } } AbstractRefreshableWebApplicationContext parentContext = (AbstractRefreshableWebApplicationContext) parentApplicationContext; ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(contexts.toArray(new String[] {}), parentApplicationContext); String[] singletonNames = context.getBeanFactory().getSingletonNames(); for (String s : singletonNames) { //copy all singletons that don't already exist from child to parent if (!parentContext.getBeanFactory().containsSingleton(s)) { parentContext.getBeanFactory().registerSingleton(s, context.getBeanFactory().getSingleton(s)); } } } } 
+4
source share
2 answers

This is exactly how I did it. We have been using this mod for over 3 years and have never experienced any problems.

+1
source

You might be able to use AutowireCapableBeanFactory. This class allows you to add beans to an existing Spring context. It will instantiate the beans and inject their dependencies.

http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/config/AutowireCapableBeanFactory.html

I'm not sure I understand the "bi-directional" context you are talking about. Do you need your main beans context to depend on beans on the "child" / additional context? If so, importing the lookups is probably the best choice, even if you don't prefer this solution.

Perhaps it would be helpful if you could explain your overall application life cycle in more detail, describing the steps for your β€œparent” / main context and your β€œchild” / secondary context.

0
source

Source: https://habr.com/ru/post/1394380/


All Articles