简体   繁体   English

Spring在运行时将一些bean添加到服务上下文

[英]Spring add some beans to service context in Runtime

I am creating spring dispatcherServlet and set his servlet context this way: 我正在创建spring dispatcherServlet并以这种方式设置他的servlet上下文:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;


import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.*;

public class MyDispatcherBean implements InitializingBean {


    @Autowired
    private ApplicationContext applicationContext;

    private DispatcherServlet dispatcherServlet;

    private final String someContext = "some.xml";

    private ServletContext servletContext;


    public void execute(/* Do some code..*/) throws IOException {

        /*
        Do some code..
        */
        try {
            dispatcherServlet.service(/* ...*/);
        } catch (ServletException e) {

        }

    }

    public WebApplicationContext getServiceContext() {
        return dispatcherServlet.getWebApplicationContext();
    }
    public void afterPropertiesSet() throws Exception {

        dispatcherServlet = new DispatcherServlet() {

            private static final long serialVersionUID = -7492692694742330997L;

            @Override
            protected WebApplicationContext initWebApplicationContext() {
                WebApplicationContext wac = createWebApplicationContext(applicationContext);
                if (wac == null) {
                    wac = super.initWebApplicationContext();
                }
                return wac;
            }

        };

        dispatcherServlet.setContextConfigLocation(someContext);
        dispatcherServlet.init(new DelegatingServletConfig());
    }

    private class DelegatingServletConfig implements ServletConfig {

        public String getServletName() {
            return "myDispatcher";
        }

        public ServletContext getServletContext() {
            return MyDispatcherBean.this.servletContext;
        }

        public String getInitParameter(String paramName) {
            return null;
        }

        public Enumeration<String> getInitParameterNames() {
            return Collections.enumeration(new HashSet<String>());
        }
    }

}

And i create that bean this way: 然后我以这种方式创建该bean:

<bean id="myDispatcher" class="some.package.MyDispatcherBean " />

Then in any place in my code can exist any numbers of beans with code that get "myDispatcher" bean and add some beans in Runtime to servlet context of DispatcherServlet: 然后,在我的代码中的任何地方都可以存在任意数量的具有通过代码获取“ myDispatcher” bean并将其在运行时中添加到DispatcherServlet servlet上下文中的bean的bean:

public class ContextAdder implements InitializingBean {


    @Autowired
    private ApplicationContext applicationContext;


    public String classPathToContext;

    public void afterPropertiesSet() throws Exception {


        DispatcherServlet dispatcherServlet = applicationContext.getBean("myDispatcher",DispatcherServlet.class);
        XmlWebApplicationContext webApplicationContext = (XmlWebApplicationContext) dispatcherServlet.getWebApplicationContext();
        XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader((DefaultListableBeanFactory) webApplicationContext.getBeanFactory());
        xmlReader.loadBeanDefinitions(new ClassPathResource(classPathToContext));

    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public String getClassPathToContext() {
        return classPathToContext;
    }

    public void setClassPathToContext(String classPathToContext) {
        this.classPathToContext = classPathToContext;
    }
}

These beans are created this way: 这些bean是通过以下方式创建的:

<bean id="adder1" class="stargate.sg_1.ContextAdder" depends-on="myDispatcher">
        <property name="classPathToContext" value="Optimus.xml" />
</bean>

<bean id="adder2" class="stargate.atlantida.ContextAdder" depends-on="myDispatcher">
        <property name="classPathToContext" value="StarShip.xml" />
</bean>

In finally I expect behaviour: each ContextAdder bean add new beans to servlet context of dispatcherServlet in myDispatcher bean. 最后,我期望有这样的行为:每个ContextAdder bean在myDispatcher bean中将新的bean添加到dispatcherServlet的servlet上下文中。

But i am afraid of some moments: 但是我害怕一些时刻:

  1. Is it only one decision of this problem? 只是这个问题的一个决定吗?
  2. Is it the best one? 这是最好的吗?
  3. Each time when i add new bean to servletContext of DispatcherServlet - will it invoke refresh of ServletContext or even ApplicationContext? 每当我将新的bean添加到DispatcherServlet的ServletContext中时,它将调用ServletContext甚至ApplicationContext的刷新吗? If it is true - does it have influence on performance? 如果是这样-对性能有影响吗?
  4. Is all lifecycles is correct? 所有生命周期都正确吗?

I believe there is a better approach, but will leave it to you to decide. 我相信有更好的方法,但是由您自己决定。

With your approach (implements InitializingBean) you are invoking your bean creation code after the bean definitions phase has completed and after the beans are being constructed. 使用您的方法(实现InitializingBean),您将在Bean定义阶段完成之后以及构建Bean之后调用Bean创建代码。 Your bean definition phase is very simple (just create "myDispatcher"). 您的bean定义阶段非常简单(只需创建“ myDispatcher”)。

I would recommend that you create/load all your bean definitions during the bean definition phase. 我建议您在Bean定义阶段创建/加载所有Bean定义。 One way to achieve this is to instead hook into the BeanFactory post processor (implements BeanFactoryPostProcessor). 实现此目的的一种方法是挂接到BeanFactory后处理器(实现BeanFactoryPostProcessor)。 At this phase Spring lets you modify existing bean definitions and more importantly for you add further bean definitions. 在此阶段,Spring允许您修改现有的Bean定义,更重要的是,您可以添加更多的Bean定义。 Now when you leave this phase, all beans will then be created in one phase. 现在,当您离开此阶段时,将在一个阶段中创建所有bean。 The approach is very natural: bean definitions are created => beans are created and wired => Done. 这种方法很自然:创建bean定义=>创建并连接bean =>完成。

public class ContextAdder implements BeanFactoryPostProcessor {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory)
        throws BeansException {

    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry)factory);

    // I)  LOAD BY PATTERN MATCHING
    //PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(factory.getBeanClassLoader());
    //for (Resource resource : resourceResolver.getResources("com/.../*.xml"))
    //reader.loadBeanDefinitions(resource);

    // II)  LOAD A SINGLE FILE AT A TIME
    reader.loadBeanDefinitions(new ClassPathResource("com/../Optimus.xml""));
    .....
}

Perhaps you can adopt this concept to your unique requirement. 也许您可以按照自己的独特要求采用此概念。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将自定义bean添加到Spring上下文 - Add custom beans to Spring context Spring boot 应用上下文中一些bean的依赖形成了一个循环: - Spring boot The dependencies of some of the beans in the application context form a cycle: 应用上下文中部分bean的依赖在Spring批处理中形成循环 - The dependencies of some of the beans in the application context form a cycle in Spring Batch 应用上下文中一些bean的依赖形成了一个循环:在spring boot - The dependencies of some of the beans in the application context form a cycle: in spring boot Spring Boot 1.5.1和“应用程序上下文中某些Bean的依赖性形成一个循环” - Spring Boot 1.5.1 and “The dependencies of some of the beans in the application context form a cycle” Spring Security:应用程序上下文中某些Bean的依赖性形成一个循环 - Spring Security: The dependencies of some of the beans in the application context form a cycle 应用上下文中一些bean的依赖在spring boot中形成循环错误 - The dependencies of some of the beans in the application context form a cycle errors in spring boot Spring在运行时添加外部spring上下文 - Spring add external spring context at runtime 如何动态地将外部定义的bean定义添加到Spring上下文? - How to dynamically add externally defined beans definitions to Spring context? 如何在Spring中以编程方式将Java中的bean添加到app-context.xml中? - How to programatically add beans in Java to the app-context.xml in Spring?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM