服务层的Spring AOP [英] Spring AOP at Service Layer

查看:24
本文介绍了服务层的Spring AOP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need some help with Spring AOP. I've the following code:

@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 上加载我的应用程序时,出现以下异常:


When I try to load my application at Tomcat, I get the following exception:

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 放在服务层时,我得到了这个异常.


I've the same configuration at Web layer to Logging my application and it works fine, but when I put AOP at Service layer I get this exception.

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

I'm using Spring MVC and at web.xml I configured to load two different contexts, one loads only @Controller and the other loads @Repository and @Service.

推荐答案

您没有注入接口,因此您需要使用 CGLIB 代理,spring 参考手册 状态:

You are not injecting an interface so you need to use CGLIB proxies, the spring reference manual states:

Spring AOP 默认为 AOP 代理使用标准的 J2SE 动态代理.这允许代理任何接口(或接口集).

Spring AOP defaults to using standard J2SE dynamic proxies for AOP proxies. This enables any interface (or set of interfaces) to be proxied.

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

Spring AOP can also use CGLIB proxies. This is necessary to proxy classes, rather than interfaces. CGLIB is used by default if a business object does not implement an interface. As it is good practice to program to interfaces rather than classes, business classes normally will implement one or more business interfaces.

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

Spring has decided to use a J2SE proxy (com.sun.proxy.$Proxy57) probably because CrudService implements an interface. To force the use of CGLIB you can tweak your XML:

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

这篇关于服务层的Spring AOP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆