首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

Spring <aop:config>疑问解决思路

2012-03-11 
Spring aop:config疑问我想通过Spring AOP实现日志功能,及在每个类的每个方法开始调用和退出时,打印日志

Spring <aop:config>疑问
我想通过Spring AOP实现日志功能,及在每个类的每个方法开始调用和退出时,打印日志。
但是,我发现一个问题,同一个类中的方法A调用方法B时,确不能在方法B调用植入日志。

代码如下:
1) 需要植入日志的类 aop.AopTest

Java code
public class AopTest {    private static final Logger logger = Logger.getRootLogger();    public void methodA() {        logger.debug("AopTest.methodA()");    }        public void methodB() {        logger.debug("AopTest.methodB()");    }        public void methodAB() {        logger.debug("AopTest.methodAB()");        methodA();        methodB();    }}


2) interceptor, aop.InterceptorTest
Java code
public class InterceptorTest {    private static final Logger logger = Logger.getRootLogger();    public void startInvoke(JoinPoint joinPoint) {        String methodName = String.format("%s.%s", joinPoint.getSignature().getDeclaringTypeName()                                                                , joinPoint.getSignature().getName() );        logger.debug("startInvoke ----------------->[" + methodName + "]");    }            public void endInvoke(JoinPoint joinPoint) {        String methodName = String.format("%s.%s", joinPoint.getSignature().getDeclaringTypeName()                                                                , joinPoint.getSignature().getName() );        logger.debug("endInvoke *******************>[" + methodName + "]");    }}


3) Spring 配置文件 ApplicationContext.xml
XML code
<?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"       xmlns:tx ="http://www.springframework.org/schema/tx"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/tx    http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aop   http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"              default-autowire="byName">        <!-- support spring annotation -->    <context:annotation-config/>    <bean id="aopTest" class="aop.AopTest"/>            <bean id="interceptorTest" class="aop.InterceptorTest"/>        <aop:config proxy-target-class="true">        <aop:aspect id="testAspect" ref="interceptorTest">            <aop:pointcut id="testPointcut" expression="execution(* aop..*.*(..))"  />                        <aop:before pointcut-ref="testPointcut" method="startInvoke"/>            <aop:after  pointcut-ref="testPointcut" method="endInvoke"/>        </aop:aspect>    </aop:config></beans>


4) 测试代码 main.Main
Java code
public class Main {    public static final ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");    public static void main(String[] args) {        AopTest aopTest = (AopTest)ctx.getBean("aopTest");        aopTest.methodAB();        aopTest.methodA();        aopTest.methodB();    }} 



5) 运行输出
程序运行后,输入如下:

[DEBUG]startInvoke ----------------->[aop.AopTest.methodAB]
[DEBUG]AopTest.methodAB()
[DEBUG]AopTest.methodA()
[DEBUG]AopTest.methodB()
[DEBUG]endInvoke *******************>[aop.AopTest.methodAB]
[DEBUG]startInvoke ----------------->[aop.AopTest.methodA]
[DEBUG]AopTest.methodA()
[DEBUG]endInvoke *******************>[aop.AopTest.methodA]
[DEBUG]startInvoke ----------------->[aop.AopTest.methodB]
[DEBUG]AopTest.methodB()
[DEBUG]endInvoke *******************>[aop.AopTest.methodB]

6) 但实际上,我想要的输出是:
[DEBUG]startInvoke ----------------->[aop.AopTest.methodAB]
[DEBUG]AopTest.methodAB()
[DEBUG]startInvoke ----------------->[aop.AopTest.methodA]
[DEBUG]AopTest.methodA()
[DEBUG]endInvoke *******************>[aop.AopTest.methodA]
[DEBUG]startInvoke ----------------->[aop.AopTest.methodB]
[DEBUG]AopTest.methodB()
[DEBUG]endInvoke *******************>[aop.AopTest.methodB]
[DEBUG]endInvoke *******************>[aop.AopTest.methodAB]
[DEBUG]startInvoke ----------------->[aop.AopTest.methodA]
[DEBUG]AopTest.methodA()
[DEBUG]endInvoke *******************>[aop.AopTest.methodA]
[DEBUG]startInvoke ----------------->[aop.AopTest.methodB]
[DEBUG]AopTest.methodB()
[DEBUG]endInvoke *******************>[aop.AopTest.methodB]

红色的文字为,缺少的输出

问题是:
1) 为什么会这样?
2) 怎样在不改动源代码 aop.AopTest.java和aop.InterceptorTest.java的情况下,实现我期待的输出?

[解决办法]
Java code
public void methodAB() {        logger.debug("AopTest.methodAB()");        methodA();        methodB();    }
[解决办法]
public class AopTest {
private static final Logger logger = Logger.getRootLogger();

//self对象也是由spring注入 private AopTest self;
private AopTest self

public void methodA() {
logger.debug("AopTest.methodA()");
}

public void methodB() {
logger.debug("AopTest.methodB()");
}

public void methodAB() {
logger.debug("AopTest.methodAB()");
self.methodA();
self.methodB(); 
}

}

热点排行
Bad Request.