当前位置: 首页 > 面试题库 >

服务层上的Spring AOP

壤驷泓
2023-03-14
问题内容

我需要有关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放在Service层时,会遇到此异常。

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


问题答案:

弹簧参考手册指出:您没有注入接口,因此需要使用CGLIB代理:

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

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

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

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


 类似资料:
  • 在我的示例中,我有一个Hibernate实体和一个DAO。 当我以这种方式使用DAO时 数据库中只保存了一行(Action2)。当我删除注释时,两行(Action1和Action2)都被保存(这是我需要的行为)。我的问题是服务层上的事务注释如何影响事务(方法executeTransaction())的执行。为什么没有服务层上的事务性注释,这两行都保存在数据库中,而只有最后一行与此注释一起保存?

  • 问题内容: 我不确定在JSF中使用MVC环境的方法是否是最佳方法。由于我想充分利用JSF,因此我想知道应该如何“设计”我的服务层(或模型,用MVC术语来讲)。 我知道View-Controller的比例应该是1到1(排除的例外)。现在应该以哪种方式设计服务层?我应该使用一项大型服务(不这样认为)吗?如果没有,我应该基于什么拆分服务? 请注意,我的服务将从Bean(MVC术语为控制器)中调用,并且服

  • 我正在使用当前层拓扑: 1)道2)服务3)控制器(演示) 在我的一个控制器中,我收到以下呼叫(来自客户端): 控制器现在应该将调用委托给服务层。 问题是,如果我创建一个如下方法: 在我的服务中,我实际上让我的服务层意识到DTO对象! 我认为这是一种不好的做法(或者不是?) 因此,我提出的另一个选择是创建一个新类: 然后调用我的控制器: 这个解决方案的问题是我在我的项目中根本没有使用这个类,所以它看

  • 这一节介绍了aiohttp.web的基础底层服务器。 抽象基础 有时候用户不需要更高级的封装,像是 application,routers和signals。 只是需要一个支持异步调用并且是接受请求返回响应对象的东西。 在aiohttp.web.Server类中有介绍过一个服务协议工厂——asyncio.AbstractEventLoop.create_server(),并可以将数据流桥接到web处

  • 答案可能涵盖所有框架,但我对SpringMVC案例特别感兴趣。我正在重构一个访问内部数据库和远程服务的服务层。这些方法应该是事务性的,它们需要来自远程服务的数据。下面是类似的伪代码: 这样更容易实现。但是有许多缺点,例如当远程服务调用失败时不必要地创建和回滚事务,由于远程服务调用而导致的事务更长,并且可能更复杂。我正在考虑将服务调用移动到单独的非事务性方法,并调用事务性方法,如下面的代码段所示 假

  • 我有一个DTO,它在控制器层通过BeanValidation(javax.validation)和定制验证器(org.springframework.validation.Validator)的组合进行验证。通过这种方式,我可以检查提供的输入是否有效,然后转换实体中的DTO并将其转发到服务层。 然后是业务逻辑验证。例如:@Entity用户的startDate必须在某个事件发生之后,如果最后创建的用