2013-10-09 26 views
1

我想用Spring AOP来分析我的控制器,但只要我启用monitoringAdvisor在我的servlet上下文xml我的@Controller类构造函数被调用两次下面提到的堆栈。@Controller类实例化了两次与春季AOP

我认为它是与CGLIB代理其从@Controller的类派生(PersonController在这种情况下)

但是,如果是这样的话那么是不是该对春天的辛格尔顿概念(假设我尝试在单身人士中获得系统资源)。 请让我知道如何在使用CGLIB代理时避免此问题。

我没有使用在web.xml中任何的ContextLoaderListener,

我-servlet.xml中

<bean id="monitoringInterceptor" class="org.javasimon.spring.MonitoringInterceptor" /> 
<bean id="monitoringAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> 
    <property name="advice" ref="monitoringInterceptor" /> 
    <property name="pointcut"> 
     <bean class="org.javasimon.spring.MonitoredMeasuringPointcut" /> 
    </property> 
</bean> 
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"> 
</bean> 
<context:component-scan base-package="org.mypackage" /> 

Java代码

@Controller 
public class PersonController { 
PersonController() 
    { 

    } 

    @Monitored // works well even when I remove this annotation 
    @RequestMapping(value="/addPerson", method=RequestMethod.POST) 
    public String addPerson(HttpServletRequest request) { 
    } 
} 

调用堆栈当org.mypackage.PersonController(类使用@Controller注解)构造函数首先命中

PersonController.<init>() line: 48 
NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method] 
NativeConstructorAccessorImpl.newInstance(Object[]) line: 57  
DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45  
Constructor<T>.newInstance(Object...) line: 526 
BeanUtils.instantiateClass(Constructor<T>, Object...) line: 148 
CglibSubclassingInstantiationStrategy(SimpleInstantiationStrategy).instantiate(RootBeanDefinition, String, BeanFactory) line: 87  
DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).instantiateBean(String, RootBeanDefinition) line: 1000 

当断点命中第二次调用堆栈

PersonController$$EnhancerByCGLIB$$4ad0c197(PersonController).<init>() line: 48 
PersonController$$EnhancerByCGLIB$$4ad0c197.<init>() line: not available  
NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method] 
NativeConstructorAccessorImpl.newInstance(Object[]) line: 57  
DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45  
Constructor<T>.newInstance(Object...) line: 526 
ReflectUtils.newInstance(Constructor, Object[]) line: 228 
ReflectUtils.newInstance(Class, Class[], Object[]) line: 220  
ReflectUtils.newInstance(Class) line: 216 
Enhancer.createUsingReflection(Class) line: 643 
Enhancer.firstInstance(Class) line: 538 
Enhancer(AbstractClassGenerator).create(Object) line: 225 
Enhancer.createHelper() line: 377 
Enhancer.create() line: 285 
CglibAopProxy.getProxy(ClassLoader) line: 205 

回答

1

找到在http://nurkiewicz.blogspot.in/2011/10/spring-pitfalls-proxying.html 回答以下

“与其子类的段落

和实例子类豆 Spring首先创建一个原豆,然后创建一个子类其中一个(有点Decorator模式)在后处理器之一“

这就是为什么构造函数获取calle d两次,但实际上只有一个bean。我尝试了@PostConstruct并且只有一次被调用,这澄清了我所有的疑惑。所以基本上只有一个bean。另一个只是一个代理。