Depending on the type of the header it can make sense to add them on dispatcher. On the other hand there are also usecases where code on the publish instance adds headers which should be delivered to the browser.
For #1 can you explain bit more in it. You mentioned there might be scenarios in which we may set the headers through code. But that is contradictory to our scenario where we are setting it through OSGI configs.
So it looks there are 3 ways to set the headers(at least) :
1. Through code - Scenario when there is a specific business logic and we need to set through code
2. Through Dispatcher - Most common scenario when headers are set on web server level only when there is no specific business logic
3. Through OSGI configs - Not sure yet. Can you help give a scenario?
I don't see a huge difference between your sceario 1 and 3 🙂 In both cases the headers are added by AEM; either through some kind of configuration and there's code to add this configured data to the response (the Sling Main servlet does that unconditioonally to every response), or you have your own code which does that for you (based on your own requirements, logic and configuration).