2013-08-21 42 views
9

Tôi cần trợ giúp với Spring AOP. Tôi đã đoạn mã sau:AOP mùa xuân ở Tầng dịch vụ


@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> { 
    ... 
} 

ứng dụng 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> 

ứng dụng bối cảnh 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> 

Khi tôi cố gắng để tải ứng dụng của tôi tại Tomcat, tôi nhận được ngoại lệ sau đây:

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 

Tôi có cùng cấu hình ở lớp Web để ghi nhật ký ứng dụng của tôi và nó hoạt động tốt, nhưng khi tôi đặt AOP ở lớp Dịch vụ, tôi nhận ngoại lệ này.

Tôi đang sử dụng Spring MVC và tại web.xml tôi đã định cấu hình để tải hai bối cảnh khác nhau, chỉ tải @Controller và tải @Repository và @Service khác.

Trả lời

16

Bạn chưa tiêm một giao diện, do đó bạn cần phải sử dụng cglib proxy, các spring reference manual trạng thái:

Spring AOP giá trị mặc định để sử dụng tiêu chuẩn J2SE proxy động cho AOP proxy. Điều này cho phép bất kỳ giao diện (hoặc bộ giao diện) nào được ủy quyền.

Spring AOP cũng có thể sử dụng proxy CGLIB. Điều này là cần thiết cho các lớp proxy, thay vì giao diện. CGLIB được sử dụng theo mặc định nếu một đối tượng nghiệp vụ không thực hiện một giao diện. Vì nó là thực hành tốt để lập trình cho các giao diện hơn là các lớp, các lớp nghiệp vụ thông thường sẽ thực hiện một hoặc nhiều giao diện nghiệp vụ.

Mùa xuân đã quyết định sử dụng proxy J2SE (com.sun.proxy.$Proxy57) có thể do thực hiện giao diện CrudService. Để buộc việc sử dụng cglib bạn có thể tinh chỉnh XML của bạn:

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

Xin chào @samlewis, cảm ơn bạn đã dành thời gian. Thực ra tôi đã đọc điều đó trước đây, nhưng khi tôi đặt 'proxy-target-class' tôi nhận được một ngoại lệ khác: ** _ Gây ra bởi: org.springframework.aop.framework.AopConfigException: Không thể tạo lớp con CGLIB của lớp [class com .sun.proxy. $ Proxy54]: Các nguyên nhân phổ biến của vấn đề này bao gồm việc sử dụng một lớp cuối cùng hoặc một lớp không nhìn thấy được; ngoại lệ lồng nhau là java.lang.IllegalArgumentException: Không thể phân lớp lớp cuối cùng com.sun.proxy. $ Proxy54 _ ** Nhưng không có trường nào trong số đó được đánh dấu cuối cùng hoặc không hiển thị. Tôi đã thay đổi Kho lưu trữ thành công khai. Tôi không có chuyện gì xảy ra cả. Cảm ơn. –

+0

_ (* Tôi không biết) _ Khi tôi rời khỏi Repository với modifier_ truy cập _default tôi nhận được ngoại lệ này: * Nguyên nhân: org.springframework.aop.framework.AopConfigException: Không thể tạo cglib lớp con của lớp [ class com.xpto.user.service. $ Proxy54]: Các nguyên nhân phổ biến của vấn đề này bao gồm việc sử dụng một lớp cuối cùng hoặc một lớp không nhìn thấy được; ngoại lệ lồng nhau là java.lang.IllegalArgumentException: Không thể phân lớp lớp cuối cùng com.xpto.user.service. $ Proxy54 * Tôi nghĩ rằng ngoại lệ xảy ra vì truy cập mặc định của giao diện UserRepository. Cảm ơn –

4

Mùa xuân đã quyết định sử dụng một proxy J2SE lẽ vì CrudService thực hiện một giao diện (com.sun.proxy $ Proxy57.).

@samlewis: Câu này bạn viết đã đẩy tôi tạo giao diện cho Dịch vụ của mình và khi tôi làm điều đó, LoggingAspect đã làm việc rất tốt. Vì vậy, tôi không sử dụng proxy-target-class = true.

Cảm ơn bạn rất nhiều vì đã dành thời gian.

Các vấn đề liên quan