追跡が困難な奇妙な問題に遭遇しました。@Aspect
XML 構成を介してシングルトン Bean としてインスタンス化されるクラス (ServiceErrorInterceptor) が定義されています。XML 構成により、依存する Bean を注入できます。
私の通常のワークフローでは、すべて正常に動作します。アスペクト クラスは適切にインスタンス化され、アドバイスが呼び出されるたびに、注入された Bean は期待どおりになります。
ただし、JUnit テストを実行すると、注入されたすべての Bean が null になります。これにより、Spring によってインスタンス化された同じシングルトン Bean ではなく、別の Bean からアドバイスが呼び出されたという結論に至ります。私の仮説をさらに検証するために、インスタンス化中に呼び出されるセッターにブレークポイントを配置し、アドバイスにブレークポイントを配置した場合、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 構成では、コンストラクターが 2 回呼び出されます (異なる Bean ID)。
- @Aspect アノテーションを削除すると、一度だけ呼び出されます。
- @Aspect を残して XML 構成を削除すると、コンストラクターは呼び出されません。
- @Component アノテーションを @Aspect と組み合わせて (ただし XML 構成なしで) 使用すると、Bean が 2 回作成されます。
- しかし、奇妙なことに、@Component および @Aspect アノテーションと XML 構成の両方を使用しても、コンストラクターはまだ 2 回しか呼び出されません。
では、XML 構成と @Aspect アノテーションの両方を使用すると、コンストラクターが 2 つの異なる Bean ID で 2 回呼び出されるのはなぜでしょうか?
さらに、AOP 定義全体を XML 構成に移動すると (@Aspect および @Pointcut アノテーションを削除)、Bean が 1 回だけ構築されることを確認しました。
編集終了
ありがとう、
エリック