akka与spring集成

看了java高并发编程,对akka的actor开发模式比较感兴趣,于是在日常一个开发任务中使用了下。

由于akka采用scala开发,对java开发者来说是黑盒。了解到akka在java里面最终是采用ForkJoinPool实现,相对于自己实现多线程并发,个人认为优势并不大。于是最终并未采用akka来实现功能。

现在将自己网上收集并跑起来的代码整理下,以便对此感兴趣的同学可以跑起来。

pom引用

注意scala和akka版本需要一致,这个我就吃了亏。

如akka-actor_2.12对应的scala需要 2.12.*版本,2.11类似。

<!-- akka -->
<dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-slf4j_2.12</artifactId>
    <version>2.5.3</version>
</dependency>
<dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-actor_2.12</artifactId>
    <version>2.5.3</version>
</dependency>
<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-library</artifactId>
    <version>2.12.3</version>
</dependency>

java类

akka spring运行环境配置。

public class DIProducer implements IndirectActorProducer {
    private ApplicationContext context;
    private String beanName;

    public DIProducer(ApplicationContext context, String beanName) {
        this.context = context;
        this.beanName = beanName;
    }

    @Override
    public Actor produce() {
        return (Actor) context.getBean(beanName);
    }

    @Override
    public Class<? extends Actor> actorClass() {
        return (Class<? extends Actor>) context.getType(beanName);
    }
}
/**
 * 扩展组件,ApplicationContext会在SpringBoot初始化的时候加载进来
 * 构造Props,用于生产ActorRef
 */
public class SpringExt implements Extension {
    private ApplicationContext context;

    public void init(ApplicationContext context) {
        System.out.println("applicationContext初始化...");
        this.context = context;
    }

    /**
     * 该方法用来创建Props对象,依赖前面创建的DI组件,获取到Props对象,我们就可以创建Actor bean对象
     *
     * @param beanName actor bean 名称
     * @return props
     */
    public Props create(String beanName) {
        return Props.create(DIProducer.class, this.context, beanName);
    }
}
/**
 * 通过继承AbstractExtensionId,我们可以在ActorSystem范围内创建并查找SpringExt
 */
public class SpringExtProvider extends AbstractExtensionId<SpringExt> {
    private static SpringExtProvider provider = new SpringExtProvider();

    public static SpringExtProvider getInstance() {
        return provider;
    }

    @Override
    public SpringExt createExtension(ExtendedActorSystem extendedActorSystem) {
        return new SpringExt();
    }
}
/**
 * 创建ActorSystem,并将其放入到spring管理,初始化ApplicationContext
 */
@Configuration
public class AkkaConfig {
    private final ApplicationContext context;

    @Autowired
    public AkkaConfig(ApplicationContext context) {
        this.context = context;
    }

    @Bean
    public ActorSystem actorSystem() {
        ActorSystem system = ActorSystem.create("system");
        SpringExtProvider.getInstance().get(system).init(context);
        return system;
    }
}

测试

注意actor需要配置成多例。

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TestActor extends AbstractActor {
    @Override
    public Receive createReceive() {
        return receiveBuilder().matchAny(o -> {
            System.out.println("接受到消息:" + o);
        }).build();
    }
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = WebApplication.class)
public class AkkaApplicationTest {

    @Autowired
    private ActorSystem actorSystem;

    @Test
    public void testContextLoads() {
        ActorRef ref = actorSystem.actorOf(SpringExtProvider.getInstance().get(actorSystem).create("testActor"), "testActor");
        ref.tell("hello", ActorRef.noSender());
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值