【问题标题】:Spring config and runtime separationSpring 配置和运行时分离
【发布时间】:2012-09-20 21:07:47
【问题描述】:

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

【问题讨论】:

  • 看看这种繁琐情况的例子会很有趣。可能有一种方法可以以不同的方式实现您想要实现的目标。
  • @Yuriy:我也许可以添加一个示例,但恐怕答案会倾向于针对该特定示例的解决方案。我对一般性讨论更感兴趣。但是为了论证,假设您正在编写一个服务器,并且您想要创建包含从请求中解析的数据的 bean。

标签: spring architecture


【解决方案1】:

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

  • 使用ApplicationContextInitializerPropertySources 添加到Enviroment
  • 使用 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 对它有好处。

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

例如,使用PropertySourcesPropertyPlaceholderConfigurer

  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 中的服务实现,这取决于容器何时刷新。 (没有破坏和刷新)。

据我所知,该框架并未提供明确的方法。

【讨论】:

  • 那么你是说鼓励将运行时数据放入spring bean中?
  • 没有,但看起来并不麻烦。该框架提供了一种在必要时执行此操作的方法,尽管不是其主要目标。
  • 是的。我的问题是为什么他们决定不把它作为主要目标。像这样限制框架是否有益?
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 2019-03-14
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    相关资源
    最近更新 更多