小编Phi*_*das的帖子

我可以在运行时替换Spring bean定义吗?

请考虑以下情形.我有一个带有bean的Spring应用程序上下文,其属性应该是可配置的,思考DataSourceMailSender.可变应用程序配置由一个单独的bean管理,让我们调用它configuration.

管理员现在可以更改配置值,如电子邮件地址或数据库URL,我想在运行时重新初始化配置的bean.

假设我不能简单地修改上面的可配置bean的属性(例如由FactoryBean或者构造函数注入创建),但必须重新创建bean本身.

有关如何实现这一点的任何想法?我很高兴收到有关如何组织整个配置的建议.没有什么是固定的.:-)

编辑

为了澄清一点:我不是问如何更新配置或如何注入静态配置值.我会尝试一个例子:

<beans>
    <util:map id="configuration">
        <!-- initial configuration -->
    </util:map>

    <bean id="constructorInjectedBean" class="Foo">
        <constructor-arg value="#{configuration['foobar']}" />
    </bean>

    <bean id="configurationService" class="ConfigurationService">
        <property name="configuration" ref="configuration" />
    </bean>
</beans>
Run Code Online (Sandbox Code Playgroud)

所以有一个constructorInjectedBean使用构造函数注入的bean .想象一下,bean的构造非常昂贵,因此使用原型范围或工厂代理不是一种选择DataSource.

我想要做的是每次更新配置时(通过configurationServicebean constructorInjectedBean重新创建并重新注入应用程序上下文和依赖bean).

我们可以放心地假设constructorInjectedBean正在使用接口,因此代理魔术确实是一种选择.

我希望能让这个问题更清楚一些.

java spring

68
推荐指数
3
解决办法
5万
查看次数

Mockito和Hamcrest:如何验证Collection参数的调用?

我遇到了Mockito和Hamcrest的仿制问题.

请假设以下界面:

public interface Service {
    void perform(Collection<String> elements);
}
Run Code Online (Sandbox Code Playgroud)

以下测试片段:

Service service = mock(Service.class);

// ... perform business logic

verify(service).perform(Matchers.argThat(contains("a", "b")));
Run Code Online (Sandbox Code Playgroud)

所以我想验证我的业务逻辑实际上是用一个包含"a"和"b"的集合来调用服务.

但是,返回类型contains(...)Matcher<Iterable<? extends E>>,所以在我的情况下Matchers.argThat(...)返回Iterable<String>,这自然不适用于所需的Collection<String>.

我知道我可以使用Hamcrest hasItem和Mockito中提出的参数捕获器验证不一致,但我非常愿意不这样做.

有什么建议!谢谢!

java generics hamcrest mockito

35
推荐指数
4
解决办法
4万
查看次数

MongoDB:如何通过子文档ID查找?

我想的概念模型games,其中teamsplayersMongoDB中相互竞争.

我有两个系列:playersgames.

这就是文档的games外观.

{
    "_id": { "$oid": "1" },
    "teams": [
        {
            "players": [
                {
                    "player": { "$oid": "2" },
                    "score": 500,
                },
                {
                    "player": { "$oid": "3" },
                    "score": 550,
                }
            ]
        },
        {
            "players": [
                {
                    "player": { "$oid": "4" },
                    "score": 500,
                },
                {
                    "player": { "$oid": "5" },
                    "score": 550,
                }
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

这是任务:给定一个玩家ID,我想找到这个玩家参与的所有游戏.

我尝试过的:

db.games.find( { "teams.players.player._id": "2" } )
Run Code Online (Sandbox Code Playgroud)

但是,这不会返回任何内容. …

mongoose mongodb

7
推荐指数
1
解决办法
2万
查看次数

Spring Integration和AMQP:如何优雅地处理反序列化异常?

我使用RabbitMQSpring Integration来处理传入的JSON消息.

配置的相关部分如下所示:

<amqp:inbound-channel-adapter channel="incomingChannel" queue-names="..."
      message-converter="jsonConverter" error-handler="errorHandler"
      error-channel="errorChannel" />
Run Code Online (Sandbox Code Playgroud)

我正在使用Jackson Databind作为JSON转换器.

有时传入的JSON消息的语法不正确.这导致以下(正确)异常:

org.springframework.amqp.rabbit.listener.ListenerExecutionFailedException: Listener threw exception
Caused by: org.springframework.amqp.support.converter.MessageConversionException: Failed to convert Message content
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token...
Run Code Online (Sandbox Code Playgroud)

然后由errorHandler例如MessagePublishingErrorHandlerto来处理异常errorChannel.

到现在为止还挺好.问题是,AMQP客户端仍然拒绝该消息,尽管我正在使用错误处理程序处理它.然后RabbitMQ一遍又一遍地重新传递消息.即使配置死信队列也无济于事.任何想法如何正确处理这种情况?

处理后的异常(成功反序列化后)处理得很好:AMQP消息已确认并发送错误消息errorChannel.

有任何想法吗?

图书馆版本:

  • Spring Integration:3.0.1
  • Spring Framework:4.0.2
  • Jackson Databind:2.3.1

amqp spring-integration rabbitmq spring-rabbit spring-amqp

6
推荐指数
1
解决办法
3082
查看次数

使用Java 8连接集合

我想迭代一系列集合.有了番石榴,我会这样做:

import static com.google.collections.Iterables.*;

class Group {
    private Collection<Person> persons;
    public Collection<Person> getPersons();
}

class Person {
    private String name;
    public String getName();
}

Collection<Group> groups = ...;
Iterable<Person> persons = concat(transform(groups, Group::getPersons()));
Iterable<String> names = transform(persons, Person::getName);
Run Code Online (Sandbox Code Playgroud)

但是我怎么能用Java 8流做同样的事情呢?

groups.stream().map(Group::getPersons())...?
Run Code Online (Sandbox Code Playgroud)

java guava java-8 java-stream

6
推荐指数
2
解决办法
2279
查看次数

Spring MVC:@SessionAttributes在控制器之间共享?

我有一个搜索和结果列表的抽象控制器支持类:

@Controller
@SessionAttributes("query")
public abstract class SearchController<Q extends SearchQuery> {
    @RequestMapping
    public String performSearch(@ModelAttribute("query") Q query) {
        ....
    }

    @ModelAttribute("query")
    public abstract Q createDefaultSearchQuery();
}
Run Code Online (Sandbox Code Playgroud)

几个实际的搜索控制器扩展了这个基类.

在访问其中一个控制器(比如/searchBooks.html使用BookSearchQuery implements SearchQuery)之后,查询被正确地存储在会话中,可用于后续请求.

但是,当我访问另一个控制器(比如/searchAuthors.html使用AuthorSearchQuery implements SearchQuery)时,来自最后一个请求()的查询BookSearchQuery仍在用于新控制器,从而导致ClassCastException稍后的操作.

我已经尝试将@SessionAttribute注释从支持类移动到实现类,但无济于事.

有什么我做错了还是这个设计?我能做什么?

非常感谢!

spring spring-mvc

5
推荐指数
1
解决办法
4168
查看次数

Java 8功能:如何计算对象的依赖进化列表?

我想以函数方式编写以下代码,包含streams和lambdas:

Thing thing = new Thing();
List<Thing> things = new ArrayList<>();
things.add(thing);

for (int i = 0; i < 100; i++) {
    thing = computeNextValue(thing);
    things.add(thing);
}
Run Code Online (Sandbox Code Playgroud)

阻碍这个......

Supplier<Thing> initial = Thing::new;
List<Things> things = IntStream.range(0, 100).???(...).collect(toList());
Run Code Online (Sandbox Code Playgroud)

java functional-programming java-8 java-stream

4
推荐指数
1
解决办法
95
查看次数

如何使用Apache Ant提取部分文件名?

我想从我的Ant脚本之外生成的文件名中提取版本号.

外部构建工具(PDE构建)artifactid-1.2.3.201101010101.jar在一个众所周知的目录中创建表单文件,但我无法预先告知版本信息.我需要1.2.3.201101010101将该文件名中的version part()提取到Ant属性中以进行进一步处理,例如变量替换.

使用ant-contrib是可以接受的,但是我还没有找到提取这些信息的方法.

ant

3
推荐指数
1
解决办法
8335
查看次数