Added support for springs @PostConstruct and @PreDestroy

This commit is contained in:
Johan Rask 2010-07-07 11:12:16 +02:00
parent 9b3aed1e29
commit 528500c366
4 changed files with 68 additions and 9 deletions

View file

@ -6,7 +6,8 @@ package se.scalablesolutions.akka.spring
import java.beans.PropertyDescriptor
import java.lang.reflect.Method
import javax.annotation.PreDestroy
import javax.annotation.PostConstruct
import reflect.BeanProperty
import org.springframework.beans.BeanWrapperImpl
@ -82,16 +83,37 @@ class ActiveObjectFactoryBean extends AbstractFactoryBean[AnyRef] with Logging w
if (hasInterface) argumentList += "i"
if (hasDispatcher) argumentList += "d"
setProperties(create(argumentList))
postConstruct(
setProperties(
create(argumentList)))
}
/**
* Stop the active object if it is a singleton.
* It will call the instance destroy method before
* stopping the active object.
*/
override def destroyInstance(instance:AnyRef) {
for(method <- instance.getClass.getMethods) {
if(method.isAnnotationPresent(classOf[PreDestroy])) {
method.invoke(instance)
}
}
ActiveObject.stop(instance)
}
private def postConstruct(ref:AnyRef) : AnyRef = {
// Invoke postConstruct method if any
for(method <- ref.getClass.getMethods) {
if(method.isAnnotationPresent(classOf[PostConstruct])) {
method.invoke(ref)
}
}
ref
}
private def setProperties(ref:AnyRef) : AnyRef = {
if(hasSetDependecies) {
return ref
@ -119,8 +141,6 @@ class ActiveObjectFactoryBean extends AbstractFactoryBean[AnyRef] with Logging w
throw new AkkaBeansException("Either property@ref or property@value must be set on property element")
}
}
//un-set so next bean can be managed
hasSetDependecies = false
ref
}
@ -144,6 +164,8 @@ class ActiveObjectFactoryBean extends AbstractFactoryBean[AnyRef] with Logging w
}
}
private[akka] def createConfig: ActiveObjectConfiguration = {
val config = new ActiveObjectConfiguration().timeout(timeout)
if (hasRestartCallbacks) config.restartCallbacks(pre, post)
@ -153,10 +175,11 @@ class ActiveObjectFactoryBean extends AbstractFactoryBean[AnyRef] with Logging w
}
def aNewInstance[T <: AnyRef](clazz: Class[T]) : T = {
var ref = clazz.newInstance().asInstanceOf[T]
setProperties(ref)
postConstruct(
setProperties(ref))
hasSetDependecies = true
ref
}
}
private[akka] def isRemote = (host != null) && (!host.isEmpty)

View file

@ -2,12 +2,16 @@ package se.scalablesolutions.akka.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PreDestroy;
import javax.annotation.PostConstruct;
public class Pojo implements PojoInf,ApplicationContextAware {
private String string;
private boolean gotApplicationContext = false;
private boolean preDestroyInvoked = false;
private boolean postConstructInvoked = false;
public boolean gotApplicationContext() {
return gotApplicationContext;
@ -23,5 +27,23 @@ public class Pojo implements PojoInf,ApplicationContextAware {
public String getString() {
return string;
}
@PreDestroy
public void destroy(){
preDestroyInvoked = true;
}
@PostConstruct
public void create() {
postConstructInvoked = true;
}
public boolean isPreDestroyInvoked() {
return preDestroyInvoked;
}
public boolean isPostConstructInvoked() {
return postConstructInvoked;
}
}

View file

@ -1,8 +1,18 @@
package se.scalablesolutions.akka.spring;
import javax.annotation.PreDestroy;
import javax.annotation.PostConstruct;
public interface PojoInf {
public String getString();
public boolean gotApplicationContext();
public boolean isPreDestroyInvoked();
public boolean isPostConstructInvoked();
@PreDestroy
public void destroy();
@PostConstruct
public void create();
}

View file

@ -72,8 +72,12 @@ class ActiveObjectFactoryBeanTest extends Spec with ShouldMatchers {
val pojoInf = ctx.getBean("pojoInf").asInstanceOf[PojoInf];
println("pojoInf = " + pojoInf.getString)
Thread.sleep(200)
assert(pojoInf.isPostConstructInvoked)
assert(pojoInf.getString == "akka rocks")
assert(pojoInf.gotApplicationContext)
ctx.close
assert(pojoInf.isPreDestroyInvoked)
}
it("should stop the created active object when scope is singleton and the context is closed") {