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

查看:104
本文介绍了服务层的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层使用相同的配置来记录我的ap plication,它工作正常,但是当我把AOP放在Service层时,我得到了这个异常。


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天全站免登陆