AOP(Aspect Oriented Programming)
スプリングの重要機能の1つAOPをためす。
下にAOP概念図。
beans2.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="man" class="jp.co.jjjjpppp.springtest.impl.Man"> <property name="houseMaker"> <ref bean="oobayashi"/> </property> </bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>jp.co.jjjjpppp.springtest.messages</value> </list> </property> </bean> <!-- イベントのキャッチ <bean id="iventCatcher" class="jp.co.jjjjpppp.springtest.impl.IventCatcher"> </bean> --> <!-- AOPの設定 --> <bean id="loggingAdvice" class="jp.co.jjjjpppp.springtest.impl.LoggingAdvice"> </bean> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref local="man" /> </property> <property name="interceptorNames"> <list> <value>advisor</value> </list> </property> </bean> <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice"> <ref local="loggingAdvice" /> </property> <property name="pointcut"> <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern"> <value>.*</value> </property> </bean> </property> </bean> </beans>
LoggingAdvice
package jp.co.jjjjpppp.springtest.impl; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.util.StopWatch; public class LoggingAdvice implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { String methodName = invocation.getMethod().getName(); StopWatch sw = new StopWatch(); sw.start(methodName); System.out.println("[LOG] METHOD: " + methodName + " is calling."); Object rtnObj = invocation.proceed(); sw.stop(); System.out.println("[LOG] METHOD: " + methodName + " was called."); System.out.println("[LOG] 処理時間: " + sw.getTotalTimeMillis() / 1000 + "秒"); return rtnObj; } }
Main (Proxyを使用するように変更)
/** * SpringFrameworkTest 2008/07/07 */ package jp.co.jjjjpppp.springtest.impl; import java.util.Locale; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class Main { /** * @param args */ public static void main(String[] args) { String[] config = { "src/configerFiles/beans.xml", "src/configerFiles/beans2.xml" }; ConfigurableApplicationContext appCon = new FileSystemXmlApplicationContext(config); System.out.println(appCon.getMessage("startMessage", null, Locale.getDefault())); Man man = (Man) appCon.getBean("proxy"); man.buyHouse(); appCon.close(); } }
実行結果
2008/07/29 15:43:30 org.springframework.context.support.AbstractApplicationContext prepareRefresh 情報: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@b02e7a: display name [org.springframework.context.support.FileSystemXmlApplicationContext@b02e7a]; startup date [Tue Jul 29 15:43:30 JST 2008]; root of context hierarchy 2008/07/29 15:43:30 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 情報: Loading XML bean definitions from file [C:\eclipse\workSpace\SpringFrameworkTest\src\configerFiles\beans.xml] 2008/07/29 15:43:30 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 情報: Loading XML bean definitions from file [C:\eclipse\workSpace\SpringFrameworkTest\src\configerFiles\beans2.xml] 2008/07/29 15:43:30 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory 情報: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext@b02e7a]: org.springframework.beans.factory.support.DefaultListableBeanFactory@16672d6 2008/07/29 15:43:31 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 情報: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@16672d6: defining beans [CC1,CC2,oobayashi,man,messageSource,loggingAdvice,proxy,advisor]; root of factory hierarchy 契約書を作成します。 2008/07/29 15:43:31 org.springframework.context.support.AbstractApplicationContext doClose 情報: Closing org.springframework.context.support.FileSystemXmlApplicationContext@b02e7a: display name [org.springframework.context.support.FileSystemXmlApplicationContext@b02e7a]; startup date [Tue Jul 29 15:43:30 JST 2008]; root of context hierarchy 2008/07/29 15:43:31 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons 情報: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@16672d6: defining beans [CC1,CC2,oobayashi,man,messageSource,loggingAdvice,proxy,advisor]; root of factory hierarchy [LOG] METHOD: buyHouse is calling. 六本木ヒルズを建築します。 ★以下の会社に協力してもらいます。 習志野建設30人2000万 国土交通省4000人20兆円 ★以下のステークスホルダーが存在します。 下請け ★以下の工法で建築します 骨組み重視 [LOG] METHOD: buyHouse was called. [LOG] 処理時間: 0秒
ぬぬ。ログの出力順番が変わった。AppContextが閉じられてからメソッドが実行されているようだ。プロキシとイベントキャッチ処理を併用する場合要注意かも。