Errors caused by ASPECTJ and schema-based AOP blends in spring

Source: Internet
Author: User
Tags aop throwable

A few days ago to add a new feature to the project to monitor the performance of certain modules, it was natural to think of using spring's AOP. There was already a similar AOP code, which was configured in schema-based form, which was joined in Spring's applicationcontext.xml:

       <bean id= "Handlerbeannameautoproxycreator"
		class= " Org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator ">
		<property name=" Beannames ">
			<list>
				<value>sampleService</value>
			</list>
		</property>
		<property name= "Interceptornames" >
			<list>
				<value>sampleAdvice</value>
			< /list>
		</property>
	</bean>        
Where Sampleservice and Sampleadvice are through:

<context:component-scan base-package= "Com.nokia.myapp"/>
Automatically introduced.

This time to add features need to monitor many classes, if according to this configuration, you need to add a lot of beans in the Beannames list, and also to modify the original Sampleadvice code to determine whether it belongs to the Sampleservice, undoubtedly increased the complexity of the program, It's not what I want. At this point consider the use of ASPECTJ annotation, programming quickly, will not destroy the current code structure, but also easy to maintain later. Following the example of the @aspectj support chapter in spring Reference document, the code is quickly written:

Package com.nokia.myapp.aop.monitor;

Import Org.aspectj.lang.ProceedingJoinPoint;
Import Org.aspectj.lang.Signature;
Import Org.aspectj.lang.annotation.Around;
Import Org.aspectj.lang.annotation.Aspect;
Import Org.slf4j.Logger;
Import org.slf4j.LoggerFactory;

@Aspect public
class newaspectjaop{
	private Logger Logger = Loggerfactory.getlogger ("profile");
	
	@Around ("Execution" (* com.nokia.myapp.client. *.*(..))")
	Public Object serviceprofile (Proceedingjoinpoint pjp) throws Throwable {//do something before method
		EXECUTION
  object ret = null;
		Throwable th = null;
		
		try {
			ret = pjp.proceed ();
		} catch (Throwable thr) {
			th = thr;
		}
		
		Do something after method execution
		
		if (th!= null) {
			throw th;
		}
		
		return ret;
	}
}
Submitting the code to the test server for testing, the result starts with the first problem encountered:

ERROR [Org.springframework.web.servlet.DispatcherServlet] [Thread-2] Context initialization failed
Org.springframework.beans.factory.BeanCreationException:Error creating Bean with Name ' Service1 ' defined in file [/opt/ Myapp/bin/web-inf/classes/com/nokia/myapp/service1.class]: Instantiation of Bean failed; Nested exception is org.springframework.beans.BeanInstantiationException:Could not instantiate Bean class [ Com.nokia.myapp.Service1]: constructor threw exception; Nested exception is org.springframework.beans.factory.BeanCreationException:Error creating beans with Name ' Service2 ': Injection of autowired dependencies failed; Nested exception is org.springframework.beans.factory.BeanCreationException:Could not Autowire field:private Com.nokia.myapp.Service1 Com.nokia.myapp.Service2.locationService; Nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:Error creating beans with Name ' Service1 ':requested Bean is currently into Creation:is there an unresolvable circular?
At Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean ( abstractautowirecapablebeanfactory.java:965) ~[spring-beans-3.0.5.release.jar:3.0.5.release]
At Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance ( abstractautowirecapablebeanfactory.java:911) ~[spring-beans-3.0.5.release.jar:3.0.5.release]
At Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean ( abstractautowirecapablebeanfactory.java:485) ~[spring-beans-3.0.5.release.jar:3.0.5.release]
At Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean ( abstractautowirecapablebeanfactory.java:456) ~[spring-beans-3.0.5.release.jar:3.0.5.release]
......

According to the prompts to view the code, found in the Service2 through the @autowired introduced Service1, and in Service1 also through the @autowired introduced Service2. It then removes the Service2 reference in Service1 and then acquires Service2 by Applicationcontext.getbean (String beanname) when needed.

Fixed the above error, test again, the program can start normally, but some programs run a strange problem: every time Applicationconext.getbeansoftype (class Class) to get Sampleservice, The other bean is always fetched, causing the program to run an exception (although there is no problem running tests in local eclipse). Using the Remote debug feature of Eclipse to debug on the development server, you find that other classes getclass () Get the class com.nokia.myapp.service2$ $EnhancerByCGLIB $ $CCADC 5e, and Sampleservice is $proxy119. Puzzled by the solution.

Finally, I consulted colleagues who were familiar with the spring framework and finally found the cause of the problem:

The same class sampleservice is monitored by @aspectj-declared AOP and AOP configured in spring's configuration file. As a result, Sampleservice implemented the Cglib three interfaces during the run, and according to the spring Reference document proxying mechanisms:

Spring AOP uses either JDK dynamic proxies or cglib to create the proxy for a given target object. (JDK dynamic proxies are preferred whenever you have a choice).

If the target object to is proxied implements at least one interface then a JDK dynamic proxy would be used. All of the interfaces implemented by the target type would be proxied. If the target object does not implement any interfaces then a CGLIB proxy'll be created. Spring is also the proxy implementation of the JDK in the Sampleservice proxy class that implements the interface, so this problem is caused.

If you find a problem, the fix is easy, just specify the Proxyfactorybean proxytargetclass attribute:

<bean id= "Handlerbeannameautoproxycreator"
class= " Org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator "p:proxytargetclass=" True >


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.