By default, all streaming event processors start handling events from the beginning of time
(because you would want to build a projection based on everything that has happened - aka the full history). That means that, when a Streaming Event Processor is not yet initialized,
by default, it is initialized starting from the tail of the stream.
If the token store configured in your application is not persistent, every time you
restart your application, the token store is completely empty. This means that all
Streaming Event Processors will be reinitialized starting from the tail. This is probably why the replay happens in your case.
With your solution, every time you restart the application, the Streaming Event Processor will be reinitialized starting from the head of the stream. In this case, you can have another problem: you may skip some events if, during the downtime of your application, other clients using the same event store have produced other events.
The correct way is to configure a persistent token store that does not lose the state of the event processors at each restart. In this way, the event processors are not reinitialized and after the restart can continue processing from where they left off.