웹 프레임웍을 위해 Spring Boot를 많이 사용하게 되며
기존 사용하는 Spring Boot에 AKKA를 내장시키는 방법을 알아보겠습니다.
빈을 통해 Akka를 SpringBoot에 내장 시키면서, Spring Boot의 Application Layout도 살펴보겠지만
Spring Boot을 사용하여 기본적인 웹 서비스 개발이 가능하다라고 가정하고 진행을 합니다.
메이븐설정
Spring Boot 1.5.9 와 Akka 2.4.8 버젼에서 테스트 되었습니다.
Application Layout
- 1 - Spring Boot의 진입점과 액터를 사용하는 샘플코드가 있습니다.
- 2 - 개발자가 설계한 각종 액터들을 집합을 시킬것입니다. 여기서 TestActor는 단순하게 받은 메시지 출력을 합니다.
- 3 - AkkaSystem의 초기화된 싱글톤 객체를 얻기위해서 SpringApplication에 빈을 등록 해야하며, Spring이 Akka의 라이프사이클을 관리해주게됩니다.
- 4 - Akka에서는 ActorOf라는 객체로 액터를 등록하며, Spring에서는 객체를 Bean으로 객체 관리합니다. 이 두가지를 동일한 인터페이스로 작동하게하는 유틸클래스입니다.
- 5 - 로그환경 통합및 Spring( application.properties) 의 외부설정과 Akka(application.confg) 의 외부설정을 할수 있는곳입니다.
Step1 - Akka 사용 준비하기 ( 3,4 )
한번만 설정을 하면 이후 거의 변경될일이 없습니다.
extension.SpringActorProducer
package com.psmon.cachedb.extension; import akka.actor.Actor; import akka.actor.IndirectActorProducer; import org.springframework.context.ApplicationContext; /** * An actor producer that lets Spring create the Actor instances. */ public class SpringActorProducer implements IndirectActorProducer { private final ApplicationContext applicationContext; private final String actorBeanName; public SpringActorProducer(ApplicationContext applicationContext, String actorBeanName) { this.applicationContext = applicationContext; this.actorBeanName = actorBeanName; } @Override public Actor produce() { return (Actor) applicationContext.getBean(actorBeanName); } @Override public Class<? extends Actor> actorClass() { return (Class<? extends Actor>) applicationContext.getType(actorBeanName); } }
extenstion.SpringExtension
package com.psmon.cachedb.extension; import akka.actor.Extension; import akka.actor.Props; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; /** * Extension to tell Akka how to create beans via Spring. */ @Component public class SpringExtension implements Extension { private ApplicationContext applicationContext; /** * Used to initialize the Spring application context for the extension. */ public void initialize(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } /** * Create a Props for the specified actorBeanName using the * SpringActorProducer class. */ public Props props(String actorBeanName) { return Props.create(SpringActorProducer.class, applicationContext, actorBeanName); } }
config.ApplicationConfiguration
package com.psmon.cachedb.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.context.event.EventListener; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import com.psmon.cachedb.extension.SpringExtension; import akka.actor.ActorSystem; @Configuration @Lazy @ComponentScan(basePackages = { "com.psmon.cachedb.services", "com.psmon.cachedb.actors", "com.psmon.cachedb.extension" }) public class ApplicationConfiguration { @Autowired private ApplicationContext applicationContext; @Autowired private SpringExtension springExtension; @Bean public ActorSystem actorSystem() { ActorSystem system = ActorSystem .create("AkkaTestApp", akkaConfiguration()); springExtension.initialize(applicationContext); return system; } @Bean public Config akkaConfiguration() { return ConfigFactory.load(); } @EventListener(ApplicationReadyEvent.class) public void doSomethingAfterStartup() { } }
다음저장소에서 작동코드 참조: