【问题标题】:Spring AOP at Service Layer服务层的 Spring AOP
【发布时间】:2013-08-21 23:27:18
【问题描述】:

我需要一些有关 Spring AOP 的帮助。 我有以下代码:


@Service
public class UserSecurityService implements UserDetailsService {

    @Autowired
    private UserService userService;
    ....
}

@Service
public class UserService extends CrudService<User, UserRepository> {

    public UserService() {
        super();
    }

    @Autowired
    public UserService(UserRepository repository) {
        super(repository);
        this.repository = repository;
    }
    ....
}

@Repository
interface UserRepository extends JpaRepository<User, String> {
     ...
}

application-context.xml

<import resource="classpath*:spring/application-context-db.xml" />
<import resource="classpath*:spring/application-context-aop.xml" />
<import resource="classpath*:spring/application-context-mail.xml" />
<import resource="application-context-security.xml" />

<context:component-scan base-package="com.xpto">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>

application-context-aop.xml

<aop:aspectj-autoproxy />
<aop:config>
    <aop:aspect id="serviceLoggingAspect" ref="serviceLoggingAspectBean">
        <aop:pointcut id="servicePointcut"
                expression="@within(org.springframework.stereotype.Service)" />

        <aop:before method="before" pointcut-ref="servicePointcut" />
        <aop:after-returning method="afterReturning" pointcut-ref="servicePointcut" returning="result" />
        <aop:after-throwing method="afterThrowing" pointcut-ref="servicePointcut" throwing="exception" />
    </aop:aspect>
</aop:config>

当我尝试在 Tomcat 上加载我的应用程序时,出现以下异常:

Caused by: java.lang.IllegalArgumentException: Can not set com.xpto.user.service.UserService field com.xpto.user.security.service.UserSecurityService.userService to com.sun.proxy.$Proxy57
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:680)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:510)
... 35 more

我在 Web 层有相同的配置来记录我的应用程序,它工作正常,但是当我将 AOP 放在服务层时,我得到了这个异常。

我正在使用 Spring MVC,在 web.xml 中我配置为加载两个不同的上下文,一个仅加载 @Controller,另一个加载 @Repository 和 @Service。

【问题讨论】:

    标签: java spring-mvc proxy aop spring-aop


    【解决方案1】:

    您没有注入接口,因此您需要使用 CGLIB 代理,spring reference manual 声明:

    Spring AOP 默认为 AOP 代理使用标准 J2SE 动态代理。这使得任何接口(或一组接口)都可以被代理。

    Spring AOP 也可以使用 CGLIB 代理。这是代理类而不是接口所必需的。如果业务对象未实现接口,则默认使用 CGLIB。由于对接口而不是类进行编程是一种很好的做法,因此业务类通常会实现一个或多个业务接口。

    Spring 决定使用 J2SE 代理 (com.sun.proxy.$Proxy57) 可能是因为 CrudService 实现了一个接口。要强制使用 CGLIB,您可以调整您的 XML:

    <aop:aspectj-autoproxy proxy-target-class="true"/>
    

    【讨论】:

    • 嗨@samlewis,感谢您抽出宝贵时间。实际上我之前读过,但是当我输入'proxy-target-class'时,我得到另一个异常:原因:org.springframework.aop.framework.AopConfigException:无法生成类的CGLIB子类[类com.sun.proxy.$Proxy54]:此问题的常见原因包括使用最终类或不可见类;嵌套异常是 java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy54 但是它们都没有标记为 final 或不可见。我将存储库更改为公开的。我不知道发生了什么事。谢谢。
    • (*我不知道) 当我使用 默认访问修饰符 离开存储库时,我得到这个异常:Caused by: org .springframework.aop.framework.AopConfigException:无法生成类 [class com.xpto.user.service.$Proxy54] 的 CGLIB 子类:此问题的常见原因包括使用最终类或不可见类;嵌套异常是 java.lang.IllegalArgumentException: Cannot subclass final class class com.xpto.user.service.$Proxy54 我认为该异常是由于 UserRepository 接口的默认访问而发生的。谢谢
    【解决方案2】:

    Spring 决定使用 J2SE 代理 (com.sun.proxy.$Proxy57) 可能是因为 CrudService 实现了一个接口。

    @samlewis:你写的这句话促使我为我的服务创建接口,当我这样做时,LoggingAspect 工作得非常好。所以,我没有使用 proxy-target-class=true

    非常感谢您的宝贵时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 2013-10-25
      相关资源
      最近更新 更多