Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Spring Scala : 스프링이 스칼라를 만났을 때

10,605 views

Published on

Springcamp 2013 with Scala에서 발표한 발표자료

Published in: Technology
  • Be the first to comment

Spring Scala : 스프링이 스칼라를 만났을 때

  1. 1. Spring Scala 스프링이 스칼라를 만났을 때 Outsider 2013.10.13 at SpringCamp 2013 with Scala
  2. 2. Outsider @Outsider outsideris@gmail.com 코딩을 좋아하는 프로그래머 봄싹, 라 스칼라 코딩단, FRENDS 등에서 활동 다양한 기술에 관심 많음 http://blog.outsider.ne.kr/ 블로그 운영
  3. 3. 이 발표에서는 스칼라로 스프링 프레임워크를 사용할 수 있는가?
  4. 4. 이 발표에서는 - 스프링 스칼라가 어떤 기능을 지원하는가? - 실제로 스칼라에서 스프링을 사용할 때는 어떤 이슈가 있는가?
  5. 5. 킬러 웹프레임워크는 없다 http://www.flickr.com/photos/familymwr/4393710839/
  6. 6. 스프링을 사용할 수 없을까?
  7. 7. Spring =
  8. 8. v1.0.0 M2 스프링 스칼라 https://github.com/spring-projects/spring-scala 스칼라로 스프링 프레임워크를 쉽게 사용하도록...
  9. 9. 스프링 스칼라 스칼라 클래스를 스프링 빈으로 연결 스프링 템플릿을 함수형식으로 사용 스칼라의 컬렉션을 의존성 주입 JavaConfig를 ScalaConfig
  10. 10. 스프링 빈 연동 문제
  11. 11. 1 public class Person { 2 private String name; 3 4 public String getName() { 5 return this.name; 6 } 7 8 public void setName(String name) { 9 this.name = name; 10 } 11 }
  12. 12. 스칼라는 자바 빈 규약을 따르지 않는다
  13. 13. 1 class Person { 2 var name:String = _ 3 }
  14. 14. 1 class Person { 2 var name:String = _ 3 4 def name():String = name 5 def name_=(n:String) = name = n 6 }
  15. 15. 1 public class Person { 2 private String name; 3 4 public String name() { 5 return this.name; 6 } 7 8 public void name_$eq(String name) { 9 this.name = name; 10 } 11 }
  16. 16. 해결책 1 @BeanProperty
  17. 17. 1 import scala.beans.BeanProperty 2 3 class Person { 4 5 @BeanProperty 6 var name:String = _ 7 }
  18. 18. 해결책 2 Spring Scala
  19. 19. 스프링 3.2+ BeanInfoFactory 전략 인터페이스 사용
  20. 20. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <repositories> <repository> <id>repository.springsource.milestone</id> <name>SpringSource Milestone Repository</name> <url>http://repo.springsource.org/milestone</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.springframework.scala</groupId> <artifactId>spring-scala</artifactId> <version>1.0.0.M2</version> </dependency> </dependencies>
  21. 21. 스프링 템플릿
  22. 22. 스프링 스칼라의 템플릿 콜백 인터페이스 함수 null 반환 Option 반환 클래스 파라미터 클래스 매니패스트
  23. 23. SimpleJdbcTemplate JmsTemplate RestTemplate TransactionTemplate
  24. 24. 1 template.send("queue", 2 new MessageCreator() { 3 public Message createMessage(Session session) 4 throws JMSException { 5 return session 6 .createTextMessage("Hello World"); 7 } 8 });
  25. 25. 1 template.send("queue") { 2 session: Session => 3 session.createTextMessage("Hello World") 4 }
  26. 26. 1 RestTemplate restTemplate = new RestTemplate(); 2 3 String result = restTemplate 4 .getForObject( 5 "http://example.com", 6 String.class);
  27. 27. 1 val restTemplate = new RestTemplate() 2 3 val result = restTemplate 4 .getForAny[String] 5 ("http://example.com")
  28. 28. ScalaConfig
  29. 29. XML JavaConfig
  30. 30. XML JavaConfig ScalaConfig
  31. 31. FunctionalConfiguration
  32. 32. 1 import org.springframework.scala. 2 context.function.FunctionalConfiguration 3 4 class ScalaExampleConfiguration 5 extends FunctionalConfiguration { 6 7 bean("foo") { 8 "Foo" 9 } 10 }
  33. 33. 1 class ScalaExampleConfiguration 2 extends FunctionalConfiguration { 3 4 bean( 5 "foo", 6 aliases = Seq("bar") 7 scope = BeanDefinition.SCOPE_PROTOTYPE) { 8 "Foo" 9 } 10 }
  34. 34. 1 class ScalaExampleConfiguration 2 extends FunctionalConfiguration { 3 4 prototype("foo") { 5 "Foo" 6 } 7 8 singleton("bar") { 9 "Bar" 10 } 11 }
  35. 35. 1 class ScalaExampleConfiguration 2 extends FunctionalConfiguration { 3 4 val conference = bean() { 5 val c = new Conference("SpringCamp") 6 c.when = "2013-10-13" 7 c.where = "코엑스" 8 c 9 } 10 11 bean("helloService") { 12 new HelloService(conference()) 13 } 14 }
  36. 36. FunctionalConfigApplicationContext
  37. 37. 1 import org.springframework.scala.context. 2! function.FunctionalConfigApplicationContext 3 4 object HelloApp extends App { 5 val context = 6 FunctionalConfigApplicationContext[ScalaExampleConfiguration] 7 val helloService = context.getBean(classOf[HelloService]) 8 }
  38. 38. 스프링 스칼라가 있으면 스칼라로 스프링을 쓸 수 있는가? http://www.flickr.com/photos/chicagoartdepartment/2919452629/
  39. 39. 스칼라로 스프링 프로젝트를 연동하려면 많은 작업이 필요하다 http://www.flickr.com/photos/joeshlabotnik/4729507364/
  40. 40. 스프링 스칼라가 해주는 일은 극히 일부다 http://www.flickr.com/photos/lenore-m/459508939/
  41. 41. Spring PetClinic http://docs.spring.io/docs/petclinic.html https://github.com/spring-projects/spring-petclinic/ http://www.flickr.com/photos/dugspr/6810252887/
  42. 42. Maven
  43. 43. 스칼라 라이브러리 추가 1 <dependencies> 2 <dependency> 3 <groupId>org.scala-lang</groupId> 4 <artifactId>scala-library</artifactId> 5 <version>2.10.1</version> 6 </dependency> 7 </dependencies>
  44. 44. v3.1.6 with scala v2.10.1 scala-maven-plugin 메이븐에서 스칼라 컴파일 및 테스트
  45. 45. 1 <plugin> 2 <groupId>net.alchim31.maven</groupId> 3 <artifactId>scala-maven-plugin</artifactId> 4 <version>3.1.6</version> 5 <executions> 6 <execution> 7 <id>scala-compile-first</id> 8 <phase>process-resources</phase> 9 <goals> 10 <goal>add-source</goal> 11 <goal>compile</goal> 12 </goals> 13 </execution> 14 <execution> 15 <id>scala-test-compile</id> 16 <phase>process-test-resources</phase> 17 <goals> 18 <goal>testCompile</goal> 19 </goals> 20 </execution> 21 <execution> 22 <phase>process-resources</phase> 23 <goals> 24 <goal>compile</goal> 25 </goals> 26 </execution> 27 </executions> 28 </plugin>
  46. 46. 프로젝트 구조 src main java test java src main java scala test java scala
  47. 47. 스칼라 클래스
  48. 48. 1 class Pet { 2 private var name:String = _ 3 4 def name():String = name 5 def name_=(n:String) = name = n 6 }
  49. 49. 1 Pet pet = new Pet(); 2 pet.name_$eq(“Dog”); 3 String n = pet.name();
  50. 50. 어노테이션
  51. 51. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Controller @SessionAttributes("visit") public class OwnerController { @RequestMapping("/owners/{ownerId}") public ModelAndView showOwner( @PathVariable("ownerId") int ownerId) { // .. } @RequestMapping( value = "visits/new", method = RequestMethod.GET) public String initNewVisitForm() { // .. } }
  52. 52. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Controller @SessionAttributes(Array("visit")) class OwnerController { @RequestMapping(Array("/owners/{ownerId}")) def showOwner( @PathVariable("ownerId") ownerId:Int) = { //.. } @RequestMapping( value = Array("/visits/new"), method = Array(RequestMethod.GET)) def initNewVisitForm = { // ... } }
  53. 53. 1 @Controller 2 public class VisitController { 3 4 private final ClinicService cs; 5 6 @Autowired 7 public VisitController(ClinicService cs) { 8 this.cs = cs; 9 } 10 }
  54. 54. 1 @Controller 2 class VisitController @Autowired() (cs: ClinicService) { 3 }
  55. 55. 어노테이션 의존성 오류
  56. 56. 컴파일시 어노테이션에 대한 의존성이 필요하다 Scala 2.11에서는 해결됨
  57. 57. [WARNING] warning: Class org.joda.convert.FromString not found continuing with a stub. [WARNING] warning: Caught: java.lang.NullPointerException while parsing annotations in joda-time-2.3.jar (org/joda/time/DateTime.class) [ERROR] error: error while loading DateTime, class file 'joda-time-2.3.jar (org/joda/time/DateTime.class)' is broken
  58. 58. 1 org.joda.time.DateTime 2 3 @org.joda.convert.FromString 4 public static DateTime parse(String s) {}
  59. 59. 1 <dependency> 2 <groupId>org.joda</groupId> 3 <artifactId>joda-convert</artifactId> 4 <version>1.5</version> 5 </dependency>
  60. 60. joda-time
  61. 61. 1 object Joda { 2 implicit 3 def dateTimeOrdering: Ordering[DateTime] = 4 Ordering.fromLessThan(_ isBefore _) 5 } 1 import Joda._ 2 dateTimes.sorted
  62. 62. Collections
  63. 63. 스칼라의 컬랙션과 자바의 컬랙션은 다르다
  64. 64. java.util. Collection List Map Set scala.collection.immutable. Iterable List Map Set scala.collection.mutable. Iterable Map Set
  65. 65. 1 import scala.collection.JavaConversions._ asJavaCollection asJavaDictionary asJavaEnumeration asJavaIterable asJavaIterator asScalaBuffer ...
  66. 66. 때로는 자바 클래스를 사용
  67. 67. error: overloaded method value query with alternatives
  68. 68. 오버라이드하는 경우 오버로딩된 메서드를 호출하는 경우 타입이 상속구조를 가진 경우
  69. 69. ModelAndView
  70. 70. 1 def initFindForm( 2 model: Map[String, Object] 3 ) = {} error: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [scala.collection.immutable.Map]: Specified class is an interface
  71. 71.
  72. 72. https://github.com/outsideris/spring-petclinic
  73. 73. - 스칼라로 스프링을 사용할 수 있다 - 스프링는 검증된 프레임워크이므로 통합하고 나면 쓸만해 보인다 - 이슈는 있지만 타입오류나 자바와 스칼라의 모양이 다른 작은 이슈들이다 - 레퍼런스는 거의 없으므로 이슈는 직접 해결해야 한다
  74. 74. Questions? http://www.flickr.com/photos/olivander/68140297/

×