使用Akka时,Akka 所管理的对象是一堆的Actor,但我们不会所有的逻辑都会写到Acotr里,比如一些持久化的DAO的Service等而这些的Service是由Spring容器所管理的,然后想把这些spring所管理的Bean能自动注入到Actor里实现过程参考官方的例子,需要定义两个类分别实现ExtensionIdProvider接口与Extension接口
该方案是参考官方的扩展的例子结合自己理解弄出的方案,对比网上其他的方案所具有优点是Spring不会对Actor产生过多依赖,创建Actor还可以使用原生的actorOf方法来创建,而不是所有actor的创建都是使用Spring来创建,因为很多情况下一个Actor不会像普通一个Spring Service Bean 那样的生命周期,actor的生命很多可能是处理一个消息生成一个actor,处理完就会被销毁。所以我的方案是Actor那个官方用法,通过扩展把拿到Spring容器的类来实现自动装配
public class SpringContextHolderExtensionImpl implements Extension {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
}
由上面的代码看到这个扩展就是只有一个ApplicationContext 字段保存Spring容器引用 。
public class SpringContextHolderExtension extends AbstractExtensionId<SpringContextHolderExtensionImpl> implements ExtensionIdProvider {
public static final SpringContextHolderExtension springContextHolderExtension = new SpringContextHolderExtension();
@Override
public SpringContextHolderExtensionImpl createExtension(ExtendedActorSystem extendedActorSystem) {
return new SpringContextHolderExtensionImpl();
}
@Override
public ExtensionId<? extends Extension> lookup() {
return springContextHolderExtension;
}
}
SpringContextHolderExtension 实现了ExtensionIdProvider 接口,顾名思义就是个Provider,当创建ActorSystem时就会调用其中createExtension方法来创建扩展实例,所以说每个扩展针对每个ActorSystem私有一个。
其中静态类变量springContextHolderExtension 就是这个扩展的标识,可以通过这个标识来获取到这个扩展
上面的两个类是定义扩展
下面的两个类是展示如何与Spring结合
AkkaConfig 这个类就是定义ActorSystemBean创建过程,在创建AcotorSystem后,就把ApplicationContext注入到扩展中
@Configuration
public class AkkaConfig {
@Autowired
private ApplicationContext applicationContext;
@Bean
public ActorSystem actorSystem() {
ActorSystem actorSystem = ActorSystem.create("herd-actor-system", akkaConfiguration());
springContextHolderExtension.get(actorSystem).setApplicationContext(applicationContext);
return actorSystem;
}
@Bean
public Config akkaConfiguration() {
return ConfigFactory.load();
}
}
public abstract class AbstractAutowiredBeanActor extends BaseActor {
@Override
public void preStart() throws Exception {
super.preStart();
ApplicationContext applicationContext = SpringContextHolderExtension.springContextHolderExtension.get(getContext().getSystem()).getApplicationContext();
try {
if (applicationContext != null) {
applicationContext.getAutowireCapableBeanFactory().autowireBean(this);
}
} catch (Exception e) {
log().error(e, e.getMessage());
}
}
}
定义AbstractAutowiredBeanActor,顾名思义它是个抽象类,重写了Actor的preStart方法,从扩展里取出了Spring容器然后为actor进行自动装配
applicationContext.getAutowireCapableBeanFactory().autowireBean(this);
需要用到Spring的管理的Bean就会直接继承AbstractAutowiredBeanActor然后使用Spring'@Autowired'就可以自动注入例子如下
public class FooActor extends AbstractAutowiredBeanActor {
@Autowired
IRobotManager robotManager;
@Override
public Receive createReceive() {
return ReceiveBuilder.create()
.build();
}
}