论坛首页 Java企业应用论坛

请教:使用spring2.0 @AspectJ注解风格进行AOP编程时遇到问题:传递参数到Advice失败。

浏览 7361 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-12-11  
请教:使用spring2.0 @AspectJ注解风格进行AOP编程时遇到问题:传递参数到Advice失败。
曾经按照spring2.0-reference-cn的说明试过多次,就是不行,郁闷。
我使用spring2.0,在进行aop应用是使用的是AspectJ 5注解风格
问题:想传递参数到Advice中,但是运行时失败,总是报错,错误stack在最后。
场景:
1. IDE: Eclipse3.2 + MyEclipse5.1, JDK1.5.7
lib: spring.jar(spring2.0),spring-aspects.jar, aspectjrt.jar, aspectjweaver.jar, aopalliance.jar

2. applictationContext-service.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"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

<!--业务逻辑,将要被切入的target-->
<bean id="nameParams" class="com.server.aspect.NameParams" />

<!--启用spring @AspectJ支持-->
<aop:aspectj-autoproxy/>

<!-- Advice: After Returning Advice Type -->
	<bean id="afterReturnNameParms" class="com.server.aspect.AfterReturnNameParams" />
</beans>

3. Business Service: com.server.aspect.NameParams
public class NameParams {

//很简单,只是组合一下名称	
	public String compositeName(String name) {
		String result = "---------> " + NameParams.class.getName() + ": " + name;
		System.out.println(result);
		return result;
	}


4. AfterReturning Advice: com.server.aspect.AfterReturnNameParams
出问题的疑点

@Aspect
public class AfterReturnNameParams {

	/**
	 * 我曾经试过这种写法:
	 * 	@AfterReturning(pointcut="execution(* com.server.aspect.NameParams.compositeName(..))", argsNames="name")
	 * 也不行										
	 */
	@AfterReturning("execution(* com.server.aspect.NameParams.compositeName(..)) && " + "args(name)")
	public void doAfter(Joinpoint joinpoint, String name) {
		String result = "-------------->after returning advice: " + name;
		System.out.println(result);
	}
}

5. 调用者Client: com.server.aspect.MyClient

public class MyClient{
	private ApplicationContext appContext;

	public MyClient() {
		String[] paths = new String[] { "/applicationContext-hibernate.xml",
				"/applicationContext-service.xml" };
		appContext = new ClassPathXmlApplicationContext(paths);
	}

	//执行业务:组合名称
	public void doTest() {
		NameParams nameParams = (NameParams) appContext.getBean("nameParams");
		nameParams.compositeName("spring aspectj");
	}
	
	public static void main(String[] args) {
		new MyClient().doTest();
	}
}

6. 执行MyClient, 结果提示如下错误:
错误堆栈比较多,但是错误不是"dataSource"(第一行中: Error creating bean with name 'dataSource')引起的
"Caused by...."后面是错误源。
因为如果我不传递参数到Advice中,则一切OK.
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [applicationContext-hibernate.xml]: Initialization of bean failed; nested exception is java.lang.AbstractMethodError: org.springframework.core.LocalVariableTableParameterNameDiscoverer$FindMethodParamNamesClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
Caused by: java.lang.AbstractMethodError: org.springframework.core.LocalVariableTableParameterNameDiscoverer$FindMethodParamNamesClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
	at org.objectweb.asm.ClassReader.accept(Unknown Source)
	at org.objectweb.asm.ClassReader.accept(Unknown Source)
	at org.springframework.core.LocalVariableTableParameterNameDiscoverer.visitMethod(LocalVariableTableParameterNameDiscoverer.java:100)
	at org.springframework.core.LocalVariableTableParameterNameDiscoverer.getParameterNames(LocalVariableTableParameterNameDiscoverer.java:50)
	at org.springframework.core.PrioritizedParameterNameDiscoverer.getParameterNames(PrioritizedParameterNameDiscoverer.java:54)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.bindArgumentsByName(AbstractAspectJAdvice.java:370)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.calculateArgumentBindings(AbstractAspectJAdvice.java:331)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.afterPropertiesSet(AbstractAspectJAdvice.java:297)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvice(ReflectiveAspectJAdvisorFactory.java:216)
	at org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.instantiateAdvice(InstantiationModelAwarePointcutAdvisorImpl.java:145)
	at org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.<init>(InstantiationModelAwarePointcutAdvisorImpl.java:96)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor(ReflectiveAspectJAdvisorFactory.java:140)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory$1.doWith(ReflectiveAspectJAdvisorFactory.java:79)
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:191)
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:168)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisors(ReflectiveAspectJAdvisorFactory.java:75)
	at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.createAspectJAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:178)
	at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:129)
	at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:68)
	at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:54)
	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:247)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:311)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1038)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:420)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:290)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:348)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:92)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:77)
	at com.server.aspect.MyClient.<init>(MyClient.java:24)
	at com.server.aspect.MyClient.main(MyClient.java:33)


7.运行成功的写法:不传递参数到Advice。(其它配置及代码不变)
AfterReturning Advice: com.server.aspect.AfterReturnNameParams

@Aspect
public class AfterReturnNameParams {

	@AfterReturning("execution(* com.server.aspect.NameParams.compositeName(..))")
	public void doAfter(Joinpoint joinpoint) {
		String result = "-------OK------->after returning advice";
		System.out.println(result);
	}
}



请大家帮助,谢谢。

   发表时间:2006-12-14  
Object[]obj= joinpoint.getArgs();
System.out.println(obj[0]);
你想要的参数就是根据参数列表的索引得到的.
0 请登录后投票
   发表时间:2007-08-29  
我也碰到了同样的问题,照文档上说,只要使用args就行
@Before("execution(* somepackage.SomeClass.someMethod(..)) && args(someParam)")
public void before(SomeType someParam){
  //do something with 'someParam'
}

但实际运行中总是报错:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someService' defined in class path resource [somepackage/applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor

Caused by: java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor

郁闷~~
0 请登录后投票
   发表时间:2007-08-29  
解决了,使用args就能够成功传递参数到advice中去。

需要加入asm的几个包:asm-2.2.3.jar,asm-commons-2.2.3.jar,asm-util.2.2.3.jar

done!

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics