I am having some problems with using AOP in the case when the advice class is wired to the bean that is being advised. Below I will try to illustrate the problem on a simple example.
I have a very simple bean that I want to be advised:
Here is my advice class:Code:package somepackage; public class TestBean1 { public void test1(){ System.out.println(this.getClass().getCanonicalName()+".test1() is called"); } }
As you can see, it contains a reference to the class TestBean1 that is being advised. Finally, here are my Spring configuration files:Code:package somepackage; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; public class TestAspectJAdvice { private TestBean1 testBean1; public void setTestBean1(TestBean1 testBean1) { this.testBean1 = testBean1; } public void advice1(){ System.out.println(this.getClass().getCanonicalName()+".advice1()"); } }
andCode:<?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"> <bean id="testBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg> <list> <value>applicationContext-aopTest.xml</value> </list> </constructor-arg> </bean> </beans>
When I try to make this work with something like this: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" 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"> <bean id="testBean1" class="somepackage.TestBean1"> </bean> <bean id="testAspectJAdvice" class="somepackage.TestAspectJAdvice"> <property name="testBean1" ref="testBean1"></property> </bean> <aop:config> <aop:aspect ref="testAspectJAdvice" > <aop:before method="advice1" pointcut="execution(* *.test1(..))" /> </aop:aspect> </aop:config> </beans>
I get an exceptionCode:BeanFactoryLocator bfl=SingletonBeanFactoryLocator.getInstance("classpath*:applicationContext.xml"); AbstractApplicationContext context=(AbstractApplicationContext)bfl.useBeanFactory("testBeanFactory").getFactory(); TestBean1 bean1=(TestBean1)context.getBean("testBean1");
One strange thing is that the same example starts working when in the second config. file I change the sequence of declaration of beans:Code:Exception in thread "main" org.springframework.beans.factory.access.BootstrapException: Unable to initialize group definition. Group resource name [classpath*:applicationContext.xml], factory key [testBeanFactory]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testBeanFactory' defined in URL [file:/H:/Projects/Work/SpringAOPTest/bin/applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.context.support.ClassPathXmlApplicationContext]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testBean1': Bean with name 'testBean1' has been injected into other beans [testAspectJAdvice] in its raw version as part of a circular reference, but has eventually been wrapped (for example as part of auto-proxy creation). This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example. Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testBeanFactory' defined in URL [file:/H:/Projects/Work/SpringAOPTest/bin/applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.context.support.ClassPathXmlApplicationContext]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testBean1': Bean with name 'testBean1' has been injected into other beans [testAspectJAdvice] in its raw version as part of a circular reference, but has eventually been wrapped (for example as part of auto-proxy creation). This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example. Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.context.support.ClassPathXmlApplicationContext]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testBean1': Bean with name 'testBean1' has been injected into other beans [testAspectJAdvice] in its raw version as part of a circular reference, but has eventually been wrapped (for example as part of auto-proxy creation). This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example. Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testBean1': Bean with name 'testBean1' has been injected into other beans [testAspectJAdvice] in its raw version as part of a circular reference, but has eventually been wrapped (for example as part of auto-proxy creation). This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:423) 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 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:82) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:78) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:156) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:683) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:621) ...
Can someone explain what's going one? I also tried using @AspectJ style annotations, and it worked perfectly without any problems but I still want to understand what is wrong with the example presented above. I will be grateful if someone helps me with this.Code:<bean id="testAspectJAdvice" class="com.lycoseurope.arch.test.aop.TestAspectJAdvice"> <property name="testBean1" ref="testBean1"></property> </bean> <bean id="testBean1" class="com.lycoseurope.arch.test.aop.TestBean1"> </bean>


Reply With Quote