Spring应用程序为bean选择了不正确的AOP代理

时间:2019-03-25 18:13:39

标签: spring proxy aop

我有一个Spring Webflow应用程序,该应用程序具有启动项,该项设置了许多与该应用程序的当前用户相关的上下文变量-它们的ID,其应用程序角色等。一项启动方法调用失败,引发以下错误

org.springframework.expression.spel.SpelEvaluationExpression EL1004E:在com.sun.proxy。$ Proxy61类型上找不到方法调用userisAuthorized(java.lang.String,null)

org.springframework.webflow.execution ActionExecutionException:执行[AnnotatedAction @ 18864e3f targetAction = [EvaluateAction @ 197b16ad expression = userService.userisAuthorized(flowScope.UserUid,flowScope.isRoleBased),resultExpression = flowScope.userAuthorized,属性= map [ [empty]]状态为'requestAccess'流的状态为'null'-操作执行属性为'map [[empty]]'

然而,真正的问题是:应用程序实际上确实为除一个特定用户外的所有用户成功地在userService bean上成功调用了userisAuthorized方法。

进行一些动态调试,并参考这个有用的SO帖子Listing Aspect-proxied beans in Spring,我已经能够确定自动接线确实找到了userService。但是它以com.sun.proxy。$ Proxy6 3 而不是$ Proxy6 1 的形式加载到应用程序上下文中。

由于错误似乎与调用时登录的用户有关,所以我猜测在实际的userService之前,上下文中可能还会注入其他代理,这可能与Spring安全配置有关,Spring是由于某种原因,它与userService bean的实际代理混淆了。但是我无法终生弄清楚为什么会发生这种情况-应用程序中的任何地方都没有其他类具有isuserAuthorized方法,并且无论如何Spring安全配置无论如何都不会扫描服务包。

安全配置

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
              http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <!-- Enable auto-wiring -->
    <context:annotation-config/>

    <!-- Scan for auto-wiring classes in spring saml packages -->  <=== package that have security proxies do NOT include service
    <context:component-scan base-package="org.trinityhealth.sarequest.security"/>
    <context:component-scan base-package="org.trinityhealth.sarequest.dao" />
    <context:component-scan base-package="org.trinityhealth.sarequest.model" />

webflow配置

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/webflow
        http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

    <on-start>
        <evaluate expression="systemAccessService.populateUserInformation(flowScope.accessRequest)" />
        <evaluate expression="externalContext.globalSessionMap.userUid" result="flowScope.userUid"/>
        <evaluate expression="externalContext.globalSessionMap.isRoleBased" result="flowScope.isRoleBased"/>
        <evaluate expression="externalContext.globalSessionMap.userRhmId" result="flowScope.userRhmId"/>
        <evaluate expression="userService.userisAuthorized(flowScope.userUid, flowScope.isRoleBased)" result="flowScope.userAuthorized"/>  <=== the failing method call
        <evaluate expression="userService.readRoleFromSecurityContext()" result="flowScope.loggedInUserRole"/>
        <set name="conversationScope.hideSteps" value="'N'" />
    </on-start>
.
.
.

服务bean接口

package org.trinityhealth.sarequest.service; <=== not in security, dao, or model package
.
. various import statements
.
public interface UserService {
.
.  bunch of method definitions, none named userisAuthorized or having a (String,char) signature
.
    public boolean userisAuthorized(String thisUserId, char isRoleBased);

}
.
.
.

带有注释的服务bean实现

package org.trinityhealth.sarequest.service; <=== not in security, dao, or model package
.
. various import statements
.
@Service("userService")
public class UserServiceImpl implements UserService {
.
. bunch of implemented Methods, none named userisAuthorized or having a (String,char) signature 
.
    @Override
    @Transactional
    public boolean userisAuthorized(String thisUserId, char isRoleBased) {
.
. implementation of userisAuthorized, which works if on-start expresssion selects correct bean
.
    }

}

0 个答案:

没有答案