Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 杜松织错春AOP豆_Java_Spring_Junit_Aop - Fatal编程技术网

Java 杜松织错春AOP豆

Java 杜松织错春AOP豆,java,spring,junit,aop,Java,Spring,Junit,Aop,我遇到了一个奇怪的问题,很难找到。我有一个类(ServiceErrorInterceptor),定义为@Aspect,通过XML配置将其实例化为单例bean。XML配置允许我注入它的依赖bean 在我正常的工作流程中,一切正常。方面类被正确地实例化,无论何时调用通知,注入的bean都是我所期望的 然而,当我运行JUnit测试时,所有注入的bean都是空的。这让我得出这样的结论:通知是从不同的bean调用的,而不是由Spring实例化的同一个单例bean。为了进一步验证我的假设,我在一个sette

我遇到了一个奇怪的问题,很难找到。我有一个类(ServiceErrorInterceptor),定义为
@Aspect
,通过XML配置将其实例化为单例bean。XML配置允许我注入它的依赖bean

在我正常的工作流程中,一切正常。方面类被正确地实例化,无论何时调用通知,注入的bean都是我所期望的

然而,当我运行JUnit测试时,所有注入的bean都是空的。这让我得出这样的结论:通知是从不同的bean调用的,而不是由Spring实例化的同一个单例bean。为了进一步验证我的假设,我在一个setter上放置了一个断点,该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>
我的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>

org.springframework
春季aop
${org.springframework.version}
org.aspectj
aspectjweaver
${org.aspectj}
我做了进一步的调试,并在虚拟构造函数中设置了断点,得到了以下结果:

  • 使用@Aspect和XML配置,构造函数被调用两次(不同的bean ID)
  • 如果我删除@Aspect注释,那么它只被调用一次
  • 如果离开@Aspect,但删除XML配置,则甚至不会调用构造函数
  • 如果我将@Component注释与@Aspect结合使用(但没有任何XML配置),那么bean将被构造两次
  • 然而,奇怪的是,对于@Component和@Aspect注释以及XML配置,构造函数仍然只调用了两次
那么,为什么XML配置和@Aspect注释都会导致使用两个不同的bean ID调用构造函数两次呢

我进一步验证了,如果我将整个AOP定义移动到XML配置中(删除@Aspect和@Pointcut注释),那么bean只构造一次

结束编辑

谢谢


Eric

除了@aspect之外,您的aspect是否有任何自动检测注释(@Component、@Service)等?如果有,这可能是不同bean似乎与配置中定义的bean一起出现的原因之一

另外,只需扫描所有配置,以确保您没有在其他地方声明这个bean


据我所知,在Junit级别上没有什么特别需要做的事情。

在SpringSource STS论坛上与大家进行了大量讨论(请参阅),结果发现这个问题与AJDT配置有关。目前,AJ正在方面中编织,Spring正在类路径上定位方面,因此它们都在执行

不幸的是,AJ maven插件缺少一个允许排除编织的配置参数;当前配置不包括LTW和CTW

因此,目前的解决方法是将
-xmlconfigurated
添加到AJ编译器标志中,然后在aop.xml管理中指定一个aop.xml文件,该文件只列出要包含在项目中的AJ方面

要使其正常工作,请将“-xmlconfigurated”添加到项目属性中 “非标准编译器选项”,然后在AspectJBuild>“aop.xml “管理”将其指向一个简单的aop.xml文件:

<aspectj> 
    <aspects> 
       <aspect name="com.fooMyNewNoneSpringAspect"/>
    </aspects> 
</aspectj>


感谢STS论坛上的Andy Clement的这一发现和解决方法。他将提出JIRA问题,以进一步解决maven插件中的这一缺陷。

您可能会发现自己处于同样的情况:您使用了新的操作符,而不是让Spring注入您的服务

记住,我们这里不是在AspectJ编译时编织。不,我们使用的是Spring AOP代理,因此Spring必须实例化对象并使用代理对其进行修饰。如果你像我一样愚蠢,在测试中创建了一个新的服务,你就不会得到任何AOP


更有理由使用AspectJ进行编译时编织,并跳过Spring AOP的所有缺点,例如运行时编织启动延迟、无法编织非公共和非最终类。

No。唯一的注释是@Aspect。此外,如果有一个额外的bean,它将作为一个重复的bean定义显示在Spring日志中。日志里什么也没有。我刚刚意识到我也在使用AspectJ将其他方面编织到其他类中,但我不明白这会如何或为什么会影响任何事情。您能否确认您正在使用Spring AOP的@Aspect注释,而不是使用AspectJ的编译时或加载时编织,如果是编译时或加载时编织,然后,将依赖项注入方面的方法有点不同:使用aspectOf工厂方法-我使用@aspect注释和SpringAOP。我为其他方面添加了一些AspectJ编织,但后来从pom和包中删除了它们。去除AJ没有任何区别。我已经用附加信息编辑了我的问题。谢谢很抱歉再次重复@Eric的话,只是想非常确定-您是否使用Eclipse和Ajbuilder(使用AJDT)enable
<aspectj> 
    <aspects> 
       <aspect name="com.fooMyNewNoneSpringAspect"/>
    </aspects> 
</aspectj>