So. BeanNameAware means right after instantiation and properties are set, Spring will call back to your bean and give it the id that it has been given.
BeanNameAware has
setBeanName(
String name) as its interface method. You can hold onto the value as an instance variable and make your toString print out a nice message.
ApplicationContextAware interface has setApplicationContext(ApplicationContext context) as its method that gets called and the ApplicationContext is passed in to it, if you needed to say call getBean somewhere in that class at anytime.
Typically, you do not implement any of these interfaces as it will couple your code to Spring. And Spring doesn't want you to do that anyway. But it is a hook to the Spring Initialization phase.
As far as post and pre initialization. Those are for BeanPostProcessors, which get run after an object has been instantiated, properties set, and all the aware interface methods have been called. There is a pre and post because BeanPostProcessors might need to do some work before your bean is initialized(run an init method for example) and some might need to work after initialization of the bean.
Example, CommonAnnotationBeanPostProcessor that is looking for @PostConstruct needs to do a pre, because the method you have @PostConstruct on is a method that you want called, because it is your initialization method. Like for instance, a Cache object, and you want to preload the Cache with data. You have to wait till all of the Cache properties have been set and dependencies injected before you could even run your init method to load data.
There there are BeanPostProcessors that create Proxies to add enterprise or AOP functionality to your code. You want that created after your bean initialization. For instance, the BeanPostProcessor that adds transactionality is looking for @Transactional and we don't want the proxy created till after your initialization.
Hope that helps clear things up.
Mark