Spring Java Configuration(2)
1回目ã«ç¶ããSpring Java Configurationã試ãã¦ã¿ããã¨æãã¾ããä»åã¯AOPãã¡ãªã¿ã«ä»å±ã®ããã¥ã¡ã³ãã«ã¯AOPã®èª¬æãç¡ãã£ãã®ã§ï¼ãããM1ãªãªã¼ã¹ï¼ããã¹ãã±ã¼ã¹ãåèã«è©¦ãã¦ã¿ã¾ãã
Spring Java Configurationã§ã®AOPå®ç¾©
injectããServiceã®ã¤ã³ã¿ãã§ã¼ã¹ã¨å®è£
ã¯ã©ã¹ãããã¦injectãããClientå®è£
ã¯ã©ã¹ã¯ãååã¨åããã®ã使ç¨ãã¾ããAOPã¯æ¢åã®å®è£
ãå¤æ´ããã«ééçã«å¦çã追å ï¼å¤æ´ï¼ã§ããã®ã売ãã§ããããå½ç¶ã¨è¨ãã°å½ç¶ã§ãã
ã§ãååã®ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ã¯ã©ã¹ã«AOPã®å®ç¾©ã追å ãã¦ãã¤ã³ã¿ã¼ã»ãã¿ãæ¸ãã¡ããã¾ãã
@Configuration public class SpringConfigurationWithAOP { @Bean public Service service() { return new ServiceImpl(); } @Bean(scope = Scope.PROTOTYPE) public SpringClient client() { return new SpringClient(service()); } // ä»åã®è¿½å é¨åã@SpringAdviceã«ãã£ã¦weavingããå ´æï¼Pointcutï¼ãæå® @Bean @SpringAdvice("execution(* sample.guice.service.*.*(..))") public LoggingInterceptor interceptor() { return new LoggingInterceptor(); } // weavingããã¤ã³ã¿ã¼ã»ãã¿ static class LoggingInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation methodInvocation) throws Throwable { String methodName = methodInvocation.getMethod().getName(); System.out.println("before: " + methodName); Object obj = methodInvocation.proceed(); // æ¬æ¥ã®å¦çãå®è¡ System.out.println("after: " + methodName); return obj; } } }
ãªãPointcutã®æå®ã¯ãSpring2.0のドキュメントãåèã«ãã¾ããã
ã§ã¯å®è¡ãã¦ã¿ã¾ãããã
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: sample.guice.springjavaconf.SpringConfigurationWithAOP$LoggingInterceptor contains no Bean creation methods or Aspect methods
at org.springframework.beans.factory.java.ConfigurationProcessor.process(ConfigurationProcessor.java:179)
ï¼ä»¥ä¸ç¥ï¼
ãããµããã¤ã³ã¿ã¼ã»ãã¿ã«Beanã®å®ç¾©ãAspectã®å®ç¾©ãç¡ãã¨ãããã確ãã«ç¡ããã©ãã ãã@Configurationã¤ãã¦ãªããã§ããâ¦ãããããã¦ã¢ããã¼ã·ã§ã³ãå
é¨ã¯ã©ã¹ã«å¼ãç¶ããä»æ§ãªãã§ããããï¼ããåããã¾ããããM1ã§ãã¾ã深追ããã¦ãä»æ¹ãªãã®ã§ããã¨ãã¾ãã
ã¨ããããLoggingInterceptorãç¬ç«ããã¯ã©ã¹ã¨ãã¦å¤ã«åºãã¦ãå度å®è¡ã
before: getResponse
after: getResponse
Re: Hello
client == anotherClient : false
client.getService() == anotherClient.getService() : true
ã§ããï¼ beforeã¨afterãã¡ããã¨åºåããã¦ããã®ã§ãæ£ããå®è¡ãããããã§ãã
ã¢ããã¼ã·ã§ã³ã«å¯¾ãã¦AOPãããã¦ã¿ã
Guiceのトランザクションの回ã§ã@Transactionalã¢ããã¼ã·ã§ã³ãã¤ããã¡ã½ããã«å¯¾ãã¦ä¸è¨ã®ããã«ã¤ã³ã¿ã¼ã»ãã¿ãæå®ãã¾ããã
bindInterceptor(any(), annotatedWith(Transactional.class), transactionInterceptor);
Spring Java Configã§ãã§ããã¯ãã¨ããäºã§ãã¢ããã¼ã·ã§ã³ãã¤ããã¡ã½ãããã¤ã³ã¿ã¼ã»ããããæå®ã試ãã¦ã¿ã¾ãã
ã¾ãServiceImplã«ã¢ããã¼ã·ã§ã³ãã¤ãã¾ãã
public class ServiceImpl implements Service { @Transactional public String getResponse(String msg) { return "Re: " + msg; } }
ä»åã¯åã«ãã°ãåºãã ããªã®ã§@Transactionalã¯ä¸é©åããããã¾ããããåããæãã®ã§ãã³ãã¤ã
ããã¦AOPã®æå®ã§ããããã£ãã®ここãè¦ãã¨Pointcutã®ä¾ã¨ãã¦
@annotation(org.springframework.transaction.annotation.Transactional)
ã£ã¦ã®ãããã®ã§ãããããã®ã¾ã¾@SpringAdviceã«æ¸ãã¦ã¿ã¾ãã
@Bean @SpringAdvice("@annotation(org.springframework.transaction.annotation.Transactional)") public LoggingInterceptor interceptor() { return new LoggingInterceptor(); }
ããã¦å®è¡
before: getResponse
after: getResponse
Re: Hello
client == anotherClient : false
client.getService() == anotherClient.getService() : true
ããã£ãä¸çºã§ä¸æãããã¾ããã
èå¯
ããããã£ãããã¦ã¾ãããSpring Java Configurationã§ã¯AOPã®å®ç¾©ãç°¡åã«ã§ããäºãåããã¾ãããAspectJãªPointcutææ³ãã¿ã¤ãã»ã¼ãã§ã¯ãªãï¼SpringIDE使ãã¨è§£æ±ºãããããã®ããï¼ãããæAspectJç¨ã®Eclipseãã©ã°ã¤ã³ã§ãJoinpointããã¼ãã³ã°ãããã§ãããï¼ã®ã¯ãã£ã¹ã¢ããã³ãã¼ã¸ã§ããããã®åæå®æ¹æ³ã¯å¤å½©ã§å¼·åã§ããã
ã¨ããäºã§ã2åã«æ¸¡ãSpring Java Configurationãç°¡åã«è¦ã¦ã¿ã¾ãããè¨å®ãå
¨ã¦å¤é¨åããã¨ããæå³ã§ã¯Guiceãããã¯ãªã¼ã³ãªã½ãªã¥ã¼ã·ã§ã³ã ã¨æãã¾ããä¸æ¹ã§Spring in Actionの人のブログï¼ãã®ã¨ã³ããªã¯ç§ã®ãããã£ã¨ã¡ããã¨èå¯ãã¦ããã®ã§ãGuiceã¨Spring Java Configurationã®æ¯è¼ã«èå³ãããæ¹ã¯ã³ã¡ã³ãæ¬å«ãã¦å¿
è¦ã§ãï¼ã§ã¯ãã³ã¡ã³ãæ¬ã§Guiceã®Bob Leeæ°ã
In the Real World, you use dependencies much more often (M) than you define them (N). If Spring were an O(N*M) solution, Guice would be an O(N) solution.
ãªãã¦åè«ãå¯ãããããã¦ãã¾ããããã¯æ®éinjectããServiceãããinjectãããã¯ã©ã¹ï¼Strutsã§ããã°Actionãªã©ï¼ã®æ¹ãå¤ããã©ãSpring Java Configurationã®å ´åããããã±ã¼ã¹ã ã¨@Beanã®ã¡ã½ãããActionæ°åæ¸ããªãããããªãããããªãã®ï¼Guiceãªã@Injectã£ã¦æ¸ãã ãã ãï¼ã£ã¦è©±ã§ãã確ãã«injectç®æã®æ示ãå¿ é æ¡ä»¶ã ã¨ããã¨ãããããäºã«ãªãããã§ãããã®è¾ºãä»å¾ã®ãªãªã¼ã¹ã§è§£æ±ºãããã®ããããªãã®ããå¼ãç¶ã注ç®ãã¦ããããã¨ããã§ãã
Spring Java Configurationã®ä»å¾
ãã®ããã¸ã§ã¯ãã®ãªã¼ãã¯Costin Leauæ°ã§ããæ°ã¯ããã¸ã§ã¯ãã®çºç«¯ã¨ãªã£ãRod Johnsonæ°ã®ããã°ã®ã³ã¡ã³ãã§
Spring JavaConfig is anything but dead. I plan to spend more time on it in April and have a release out ASAP - probably end of April/May.
ã¨çºè¨ãã¦ããã®ã§ããã¨ï¼ãµæãããå¾ ã¤ã¨é²æããããç¥ãã¾ããã楽ãã¿ã§ãã