Hi,
yes, we have considered using proxies, but they come with an array of issues and problems of their own.
The andThen() solution is part of Axon 3, which was released last week. That should surely improve the code needed to guarantee ordering (in the constructor).
Regarding the interface with default methods, I don't really see how that would simplify things. You will still need the framework to interfere when "running" your model. Passing the Aggregate Root to the apply() method was something we have considered, but that would only really help when you're applying form the aggregate root itself. Otherwise, all entities within the aggregate would need to maintain a reference to the root. Something that, again, restricts modelling freedom.
We don't pretend that you can run your model without Axon. Honestly, I don't think it makes much any sense to aim for that. However, we do want to prevent Axon to impose certain restriction that make certain problems harder to model.
Note that the restrictions around apply() are only valid when using Event Sourcing. But in that case, it's Event Sourcing itself that imposes those restrictions anyway. The constructor is the only unfortunate situation where this doesn't work.
If you're not using Event Sourcing, you can use any method you like to publish your events. Injecting the EventBus into your @CommandHandler methods is one of your options.
But with all that, we're still open to any suggestions on improving the separation of framework and model....
Cheers,
Allard