我遇到了一个奇怪的问题,我很难追踪。我有一个类 (ServiceErrorInterceptor) 定义为@Aspect
通过 XML 配置实例化为单例 bean。XML 配置允许我注入它的依赖 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 {
...
...
}
我查看了日志(我启用了 spring 跟踪日志),但没有看到任何突出的内容。在这里发布整个日志可能会有点矫枉过正。如果日志的特定部分有价值,请告诉我,我会发布。
如果有帮助,我可以发布我的方面、我的 junit 和我的配置的代码。
application-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");
}
}
我的 pom 的相关部分:
<!-- 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 会被构造两次。
- 然而,奇怪的是,使用 @Component 和 @Aspect 注释以及XML 配置,构造函数仍然只调用了两次。
那么,为什么同时拥有 XML 配置和 @Aspect 注释会导致构造函数被调用两次,并使用两个不同的 bean id?
我已经进一步验证,如果我将整个 AOP 定义移动到 XML 配置中(删除 @Aspect 和 @Pointcut 注释),那么 bean 只会构造一次。
结束编辑
谢谢,
埃里克