spring aop 2.0 編程(三)

www.javabc.com

前面這是講了許多的概念,下面以一個例子來說明:
一個很好理解的aop 例子,也就是日誌服務。
先從aop第一種方式來實現,也就是xml配置方式
先創建基本的日誌類:
public class Logger {

    private static Log log = LogFactory.getLog(Logger.class);

    public void entry(String message) {
        log.info(message);
    }
}
這裏只是簡單的一個方法,當然實際情況可能不同。
由於xml配置需要一個方面的實現bean
所以創建一個簡單的bean :
public class LogBean {

    private Logger logger = new Logger();

    public Object aroundLogCalls(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.entry("before invoke method:"
                     + joinPoint.getSignature().getName());
        Object object = joinPoint.proceed();
        logger.entry("after invoke method:"
                     + joinPoint.getSignature().getName());
        return object;
    }
}
這裏採取簡單的around advice,其他類型的advice 基本上都差不多

當然有了這兩個核心的日誌類,需要一個測試類,用於測試。
public class TestBean {

    public void method1() {
        System.out.println("in method1");
    }

    public void method2() {
        System.out.println("in method2");
    }
}
這就是需要測試的類了,需要記錄日誌的方法只有兩個,這裏用System.out.println,只是想顯示方法的調用順序。


然後關鍵的在於xml的配置了

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
 
 <aop:config>
    <!--  expression 表示要執行的匹配表達式,這裏匹配所有的public方法,但是去除logger類的所有方法,防止無限調用-->

      <aop:pointcut id="loggableCalls"
          expression="execution(public * *(..)) and !execution(* org.spring.test.aop.log.Logger.*(..))"/>


  <aop:aspect id="logAspect" ref="logBean">
   <aop:around pointcut-ref="loggableCalls" method="aroundLogCalls"/>
  </aop:aspect>
 
 </aop:config>
 <bean id="logBean" class="org.spring.test.aop.log.LogBean" />
 <bean id="testBean" class="org.spring.test.aop.log.TestBean"/>
 
</beans>

現在寫一個測試類:

public class LogXmlTest extends RootTest {

    @Override
    protected String getBeanXml() {
        return "org/spring/test/aop/log/bean.xml";
    }

    public void testLog() {
        TestBean bean = (TestBean) ctx.getBean("testBean");
        bean.method1();
        bean.method2();
    }

}

public abstract class RootTest extends TestCase {

    protected ApplicationContext  ctx;

    protected Log log = LogFactory.getLog(getClass());

    protected RootTest() {
        ctx = new ClassPathXmlApplicationContext(getBeanXml());
    }

    protected abstract String getBeanXml();

}

打印的消息如下:
2006-09-17 11:08:28,203 INFO [org.spring.test.aop.log.Logger] - before invoke method:method1
in method1
2006-09-17 11:08:28,203 INFO [org.spring.test.aop.log.Logger] - after invoke method:method1
2006-09-17 11:08:28,218 INFO [org.spring.test.aop.log.Logger] - before invoke method:method2
in method2
2006-09-17 11:08:28,218 INFO [org.spring.test.aop.log.Logger] - after invoke method:method2

第二種實現方式,採用註釋方式:

Logger 類不變
創建一個LogAspect類
@Aspect
public class LogAspect {

    private Logger logger = new Logger();

    @Pointcut("execution(public * *(..))")
    public void publicMethods() {

    }

    @Pointcut("execution(* org.spring.test.aop.log.Logger.*(..))")
    public void logObjectCalls() {

    }

    @Pointcut("publicMethods()&&!logObjectCalls()")
    public void loggableCalls() {

    }

    @Around("loggableCalls()")
    public Object aroundLogCalls(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.entry("before invoke method:"
                     + joinPoint.getSignature().getName());
        Object object = joinPoint.proceed();
        logger.entry("after invoke method:"
                     + joinPoint.getSignature().getName());
        return object;
    }
}

配置文件就簡單多了
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
 
 <aop:aspectj-autoproxy/>
 
 <!-- 或者使用以下定義
 
 
 
 <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
 
 -->
 <bean id="logAspect" class="org.spring.test.aop.log.LogAspect"/>
 <bean id="testBean" class="org.spring.test.aop.log.TestBean"/>
 
</beans>

測試類:
跟上面的差不多
把xml文件換掉就行

打印的方式差不多

個人還是比較喜歡第二種實現。

 

發佈了9 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章