Messages are grouped by CorrelationStrategy. In your case it is a default one:
I'm hoping for 3 groups to be created
From other side you tell to the aggregator:
So, it creates a MessageGroup based on CORRELATION_ID. And if all your 25 inbound Messages have the same CORRELATION_ID, the aggregator creates the group on first Message and it will by only one group in the MessageStore for these 25 Messages. Further it releases Messages on expiry by reaper as a list of 10 and only once. And, of course, never removes this group, because expire-groups-upon-completion="false". In this case the MessageGroup will be marked as "completed" and won't allow any new Message. It is a scenario "Late arrival" .
release-strategy-expression="size() == 10"
There is a discardChannel on the AbstractCorrelatingMessageHandler. It allows to you to handle "Late arrival" Messages.
It's about theory.
And now a question: what do you want to achieve?