You can achieve bytecode injection with Java Agents.
A java Agent is a library that intercepts the bytecode loading at the classloader, and enhances it before it is loaded in the JVM. Of course, such a library usually relies on bytecode manipulation librairies such as Javassist, ASM or CGLib.
So the bytecode manipulation is only done once, when the class is loaded.
See the official Javadoc :
http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html
This article explains how to do pretty much what you want to:
http://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html
Also, if you're really interested in bytecode fundamentals, this article from one of the JRebel developers should please you:
http://arhipov.blogspot.com/2011/01/java-bytecode-fundamentals.html
Finally, you can take a look at Seren, a librairy I just began to write. It is a Java Agent that enhances serializable classes. It's just the beginning, but it works.
https://github.com/oliviercroisier/seren