@Autowire returns 在抽象基础 class 中添加 Spring AOP 后为 null

@Autowire returns null after adding Spring AOP in an abstract base class

我在我的 selenium 自动化项目中使用 POM,所以有一个抽象 class BasePage 由用于测试方法的 DerivedPage 扩展

returns Webdriver 在应用aop 之前有效,但在aspect 注释之后一直返回null 的方法。

在我看来,spring aop 代理包装了 DerivedPage 的原始实例,它已经初始化了 Webdriver,并覆盖 getDriver 以获取它。但它并没有像预期的那样工作。

我知道有两个继承:BasePage -> DerivedPage -> AOP Proxy,但是想不通为什么不能获取@Autowired对象。

示例底页

@Component
@Scope("cucumber-glue")
public abstract class BasePage {
    @Autowired protected WebDriver driver;

    @PostConstruct
    private void postConstruct() {
        PageFactory.initElements(driver, this);
    }

    //driver found after remove this aspect annotation
    @TakeScreenshot
    public WebDriver getDriver() {
        return driver;
    }

派生页面示例

@Component
@Scope("cucumber-glue")
public class DerivedPage extends BasePage {
    @FindBy(css = "a[href*=\"member\"]#custom-btn")
    public WebElement memberButton;
}

示例方面 Class

@Aspect
@Component
public class ScreenshotAspect {
    @Around("@annotation(TakeScreenshot)")
    public void take(){
        ScreenshotUtil.doCaptureFullScreen();
    }
}

示例测试方法

public class SampleSteps {
    @Autowired
    private DerivedPage derivedPage;

    @Test
    public void test() {
        System.out.println(derivedPage.getDriver()); //returns null, but screenshot was taken
    }

}

编辑:

我在这里发布了一个简单的 MCVE 项目来重现这个问题 https://github.com/Cordifhyura/Spring-AOP-issue

结果:

Testing started at 14:10 ...
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.6)

Starting ChromeDriver 100.0.4896.60 (6a5d10861ce8de5fce22564658033b43cb7de047-refs/branch-heads/4896@{#875}) on port 40627
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
[2022-04-28 14:10:48.832] - 31332 INFO [Forwarding newSession on session null to remote] --- org.openqa.selenium.remote.ProtocolHandshake: Detected dialect: W3C
Starting - enter holo homepage and click member
ChromeDriver: chrome on WINDOWS (898dda5b1132c26741c8f8db732c1dc1) **//direct Webdriver reference in Hooks**
base.PO.HoloPage$$EnhancerBySpringCGLIB$08317
simulate screen capture
null **//.getDriver() in pageobject**

1 Scenarios (1 passed)
1 Steps (1 passed)
0m4.255s

正如您所见,驱动程序已正确注入到 Hook 中,因此与 DI 或黄瓜无关。它只是在 AOP 代理实例中丢失了。

ScreenshotAspect 不正确。

@Around 建议应具有有效的 proceed(),如文档部分所述:Around Advice

请通读以“开头的信息部分如果您将周围建议方法的 return 类型声明为 void,则 null 将始终 returned 给调用者,.." 以及了解什么可能导致空值被 returned.