3

使用 Spring 时,将运行时数据合并到 bean 构造中是相当麻烦的。虽然有一些技术可以规避这种分离,但我觉得它是有原因的。我的问题是这是否是一个已知的范式,以及是否有任何文献讨论它。我个人发现它既有优点也有缺点,具体取决于应用程序的动态性。

4

2 回答 2

3

您至少有五个众所周知的方法可以将运行时数据传递给 bean 配置:

  • 用于ApplicationContextInitializer添加PropertySourcesEnviroment.
  • 使用 SPEL 注入依赖项。
  • 利用FactoryBeans.
  • 使用factory-beanfactory-method属性。
  • 如果你编写需要运行时数据的类,你只需要注入提供它的协作者。

例如

     <bean id="requestAttributeReader" class="example.RequestAttributeReader" />

    <bean id="requestInjectedBean" class="example.RequestInjectedBean" scope="request">
        <property name="a" value="#{requestAttributeReader.a}" />
    </bean>

    Class RequestAttributeReader {

          public String getA() {
               return RequestContextHolder.getAttributes().getAttribute("a");
         }
    }

编辑

IoC 容器的 bean 描述文件允许您在应用程序 bean 上配置实现器。这通常是您要用于具体配置的实现类的静态定义,因此 xml 对它有好处。

如果你需要根据运行时选择一个实现者,那么你需要编写代码来选择它们,然后通知容器。

例如,使用PropertySourcesand PropertyPlaceholderConfigurer

  String service = "example.NormalService";

    if (BOSS_USERNAME.equals(System.getProperty("user.name")))
        service = "example.BossService";     

    ctx.getEnvironment().getPropertySources().addFirst(new PropertiesPropertySource("service", service)); 

    <bean id="service" class="${service}" />

ServiceFactoryBean、外部 ServiceFactory、SPEL 等也可以这样做......

也许,您对在运行时替换实现感兴趣,即更改所有 bean 中的 Service 实现,这取决于容器何时刷新。(没有破坏和刷新)。

据我所知,该框架没有提供明确的方法来做到这一点。

于 2012-09-18T21:16:38.757 回答
2

听起来你应该看看弹簧绑定,例如:

public String create(@Valid Market market, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {

因此,这将采用与 Market 对象中的字段匹配的请求参数并将它们设置在该对象中。它还将验证参数/对象,因为有 @Valid 注释。可以使用 PropertyEditors 或 Converters 自定义此绑定。

如果市场对象被注解为@Configurable,那么它可以在spring创建它时使用@Autowired和@Value注解来配置bean。

于 2012-09-19T00:30:03.173 回答