Hi Ian,
your Aggregate root can simply extend from AbstractAggregateRoot if you don't care about event sourcing. If you're using JPA, you can use the GenericJpaRepository to reconstruct your aggregate based on the data in a database. To publish events, you can use the "registerEvent" method. This will use the UnitOfWork to ensure the events are published at an appropriate time.
If you don't use Aggregates at all, and wish to publish events from an @CommandHandler directly, consider using the EventTemplate instead of using the EventBus directly. The former will use the UnitOfWork to coordinate activity. The Events will be published when the Unit of Work commits.
If you have activity with side effects, as Jan mentioned, consider using a UnitOfWorkListener to perform this action when the Unit of Work has finished committing (onAfterCommit). This way, your side effect will only happen when the transaction has successfully completed. You can use the static CurrentUnitOfWork.get() to get a reference to the Unit of Work. If you use @EventHandler anntotated methods, you can add a parameter of type UnitOfWork to your method as well. Axon will inject the current UoW for you. On this UnitOfWork, use registerListener(...) to register a listener.
Hope this helps.
Cheers,
Allard