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.
These annotations MUST be adhered to by a container.
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
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.
Called when a bean is no longer required and being destroyed by the container. This method MUST be called by all containers.
See Other Annotations for more ideas of optional annotations.
The following pseudocode illustrates the containers contract
public 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 {
...
}
}
|
Cheese c = new Cheese() c.setDataSource(foo); c.setTimeout(123); // optional c.start(); |
Note 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"/> |
We 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.
Lots 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 |
A 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.
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.
Many thanks to Hani Suleiman for help creating this document and giving feedback from the JSR 250 expert group.