componentListener + annotation-driven