How to perform a custom code injection?
Hi,
I've recently started to explore annotations and wonder if something like @Resource injection could be accomplished with a custom define annotation. My intent here, is to inject some runnable source in the generating class file.
I'd appreciate if somebody could illustrate this concept through an example here.
[335 byte] By [
R.P.Roya] at [2007-11-27 5:20:50]

# 1
having not used resource injection but having used annotations for a similar purpose, i'll try an illustration based on http://java.sun.com/javaee/5/docs/tutorial/doc/Resources4.html
Field-Based Injection
To use field-based resource injection, declare a field and decorate it with the @Resource annotation. The container will infer the name and type of the resource if the name and type elements are not specified. If you do specify the type element, it must match the field's type declaration.
package com.example;
public class SomeClass {
@Resource
private javax.sql.DataSource myDB;
...
}
to resolve Resource at runtime the container uses reflection to create the JNDI lookups -- something like
// within the container the Resource resolver must be passed the
// class and instance for Resource resolution
private <T extends Object> T resourceResolver(
Class<T> resolveeClass,
T resolveeInstance ) {
// get all fields declared in the class
Field[] fields = resolveeClass.getDeclaredFields();
for( Field field : fields ) {
// check each field for Resource annotation
Resource resource = field.getAnnotation( Resource.class );
if( resource != null ) {
// resolve Resource name
String name = resource.name();
if( name.length() == 0 ) { name = field.getName(); }
String jndiName = resolveeClass.getSimpleName()+'/'+name;
// resolve Resource type
Class<?> jndiType = resource.type();
if( jndiType.equals( void.class ) ) { jndiType = field.getClass(); }
// create connection and do jndi lookup
Context ctx; // initialize
Object lookedUp = null;
try {
lookedUp = field.getClass().cast(ctx.lookup( jndiName ) ) ;
// assign the lookedUp value to the field
// in case we do not have access to the field, force it
// using reflective hack
// WARNING: this does not work on a final field
// (haven't tried it but resource injection shouldn't work
// if the field is declared final)
field.setAccessible( true ); // reflective hack
field.set( resolveeInstance, lookedUp );
//} catch( NamingException ne ) {
} catch( Exception e ) {
System.out.println( "Failed resource injection for "+
field.getClass()+'.'+field.getName() );
e.printStackTrace();
}
}
}
// resolveeInstance now has all field Resource injected
return resolveeInstance;
}
you can write your own annotations and reflect as illustrated to inject values