我遇到了一个奇怪的问题,我很难追查到。我有一个类(ServiceErrorInterceptor)定义为@Aspect
,它通过XML配置实例化为单例bean。 XML配置允许我注入它的依赖bean。JUnit编织错误Spring AOP Bean
在我的正常工作流程中,一切正常。方面类正确实例化,每当调用通知时,注入的bean就像我所期望的那样。
但是,当我运行我的JUnit测试时,所有注入的bean都是空的。这使我得出这样的结论,即建议是从一个不同的bean调用的,而不是由Spring实例化的单一bean。为了进一步验证我的假设,我在实例化过程中调用的setter上放置了一个断点,并且如果我在我的建议中放置了断点,请参阅bean id与bean id不同。
是否有一些特殊的配置,我必须在我的JUnit类中启用才能解决这个问题?我的测试类已经被标注有:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:spring/applicationContext-base.xml",
"classpath:spring/applicationContext-calculateServices.xml",
"classpath:spring/applicationContext-dom.xml"})
public class LendingSimulationServiceImplTest {
...
...
}
我已经通过日志看(我启用了春天跟踪日志),但没有看到任何脱颖而出。在这里发布整个日志可能会过度。如果在日志的特定部分有价值,请让我知道,我会发布它。
我能够发布我的代码的方面,我的junit和我的配置,如果这是有帮助的。
应用context.xml的片段:
<!-- SPRING ASPECT BEAN. POINTCUT DEFINED IN BEAN WITH ANNOTATION -->
<bean id="serviceErrorInterceptor" class="com.cws.cs.lendingsimulationservice.error.ServiceErrorInterceptor" scope="singleton">
<property name="errorMessageProvider" ref="resourceBundleProviderImpl"/>
<property name="defaultLocale">
<util:constant static-field="java.util.Locale.ENGLISH" />
</property>
</bean>
任何建议,将不胜感激。
编辑
我的bean被实现为:
@Aspect
public class ServiceErrorInterceptor {
/**
* Logger
*/
private static final Logger logger = LoggerFactory.getLogger(ServiceErrorInterceptor.class);
/**
* SOAP Header data
*/
@Autowired
private SOAPHeaderData soapHeaderData;
public ServiceErrorInterceptor(){
int x = 0;
x=x+1;
}
/**
* Exception Interceptor.
* @param ex
*/
@AfterThrowing(pointcut = "execution(* com.cws.cs.lendingsimulationservice.process.CalculatorProcess.calculate (..))", throwing = "ex")
public void errorInterceptor(Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug("Error Message Interceptor started");
}
}
我的聚甲醛的相关部分:
<!-- Aspect Oriented Programming (AOP) Framework (depends on spring-core,
spring-beans) Define this if you use Spring AOP APIs (org.springframework.aop.*) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- Support for AspectJ Annotations -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${org.aspectj}</version>
</dependency>
我已经做了进一步的调试,并把一个断点在假构造函数,我得到如下结果:
- 使用@Aspect和XML配置,构造函数被调用两次(不同的bean ID)
- 如果我删除@Aspect注释,那么它只被调用一次。
- 如果离开@Aspect但删除XML配置,则甚至不会调用构造函数。
- 如果我将@Component注释与@Aspect结合使用(但没有任何XML配置),那么这个bean会被构造两次。
- 然而,奇怪的是,对于XML配置@Component和@Aspect注释和,构造函数仍然只调用两次。
那么为什么要同时使用XML配置和@Aspect注释会导致构造函数被两次不同的bean ID调用两次?
我进一步验证,如果我将整个AOP定义移动到XML配置中(移除@Aspect和@Pointcut注释),那么这个bean只构造一次。
编辑完
感谢,
埃里克
不可以。唯一的注释是@Aspect。另外,如果有一个额外的bean,它将在Spring日志中显示为一个重复的bean定义。日志中没有任何东西。我只是意识到我正在使用AspectJ以及其他方面编织其他类的其他方面,但我不知道如何或为什么会影响任何东西。 – 2012-04-13 01:05:05
您是否可以确认您在Spring AOP中使用了@Aspect注释,而不是使用AspectJ编译时间或加载时间织入,如果是编译时或加载时编织,那么注入到某个方面的依赖关系有点不同:使用aspectOf工厂方法 - http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html – 2012-04-13 13:45:20
我在Spring AOP中使用@Aspect注释。我添加了一些AspectJ编织的其他方面,但已经从pom和包中删除它们。去除AJ没有任何区别。我用更多的信息编辑了我的问题。谢谢! – 2012-04-13 15:46:55