XBean > Home > Features > Annotation based Dependency Injection |
|
So imagine a clean slate where we make a new IoC mechanism. We'd mostly just use a few annotations to declare the IoC contract - reusing standards where possible such as JSR 250 for the annotations and JNDI as the access mechanism to the container. General guidelines for IoC
Mandatory AnnotationsThese annotations MUST be adhered to by a container. @Resource (from JSR 250)Indicate a place in a naming system, such as JNDI where the resource should be fetched from. We assume here that using @Resource marks stuff as mandatory @PostConstruct (from JSR 250)This method MUST be called after the constructors and property setters have been called. May throw any exception to indicate that the bean could not be configured properly. @PreDestroy (from JSR 250)Called when a bean is no longer required and being destroyed by the container. This method MUST be called by all containers. Other AnnotationsSee Other Annotations for more ideas of optional annotations. Contract summaryThe following pseudocode illustrates the containers contract
Example POJOpublic class Cheese { private DataSource dataSource; private int timeout = 100; @Resource public void setDataSource(DataSource ds) { this.dataSource = ds; } public void setTimeout(int timeout) { this.timeout = timeout; } @PostConstruct public void start() throws Exception { ... } } Example ContainersJava codeCheese c = new Cheese() c.setDataSource(foo); c.setTimeout(123); // optional c.start(); JAXB 2Note that we'd have added an annotation or two from JAXB 2 to achieve the following. Namely adding @XmlIDREF to the setDataSource property <cheese dataSource="customerDb" timeout="456"/> Integrating with existing IoC containersWe should be able to add the lifecycle annotations to any existing lifecycle interfaces we have. e.g.
So by adapting the existing lifecycle interfaces folks have to the DI containers we'd be able to move to ANDI while still supporting existing IoC containers like Spring POJOs etc. Dealing with legacy codeLots of code today uses old lifecycle interfaces. Lots of this code has been around for a while and will not be moving to exclusive Java 5 only any time soon. So supporting a simple way to wire in lifecycle interfaces to AnDI containers would be useful. Here's one suggestion for how we can do it.
interfaceName#methodName = PostConstruct interfaceName#methodName = PreDestroy e.g. to support any Spring POJO just ensure the following is on the classpath. org.springframework.beans.factory.InitializingBean#afterPropertiesSet = PostConstruct org.springframework.beans.factory.DisposableBean#destroy = PreDestroy Exposing the IoC container to Java codeA natural way to expose the IoC container to Java code is via a JNDI provider. That way folks can write to the JNDI standard to look up POJOs in the initial context, nor navigate to child contexts without using an IoC container-specific API. Issues with JSR 250
Note that lifecycle annotations like @PostConstruct and @PreDestroy can be used on methods on an interface (such as in Spring's InitializingBean and DisposableBean) and then be inherited on any POJO. CreditsMany thanks to Hani Suleiman for help creating this document and giving feedback from the JSR 250 expert group. |