You can do this with AspectJ.
Create an @Configurable annotation:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface Configurable { }
Create an AspectJ @Aspect similar to this:
@Aspect public class ConfigurableInjectionAspect { private Logger log = Logger.getLogger(getClass().getName()); @Pointcut("@within(Configurable) && execution(*.new(..)) && target(instantiated)") public void classToBeInjectedOnInstantiation(Object instantiated) {} @After(value = "classToBeInjectedOnInstantiation(instantiated)", argNames = "instantiated") public void onInstantiation(Object instantiated) { Injector injector = InjectorHolder.getInjector(); if (injector == null) { log.log(Level.WARNING, "Injector not available at this time"); } else { injector.injectMembers(instantiated); } } }
Create (and use) a hold class for your injector:
public final class InjectorHolder { private static Injector injector; static void setInjector(Injector injector) { InjectorHolder.injector = injector; } public static Injector getInjector() { return injector; } }
Set up META-INF / aop.xml:
<aspectj> <weaver options="-verbose"> <include within="baz.domain..*"/> <include within="foo.bar.*"/> </weaver> <aspects> <aspect name="foo.bar.ConfigurableInjectionAspect"/> </aspects> </aspectj>
Start your virtual machine with aspectjweaver:
-javaagent:lib/aspectjweaver.jar
Annotate your domain classes:
@Entity @Table(name = "Users") @Configurable public class User { private String username; private String nickname; private String emailAddress; @Inject private transient UserRepository userRepository public User() {} }
Craig day
source share