1

我需要从接口拦截方法,并找到了 MethodInterceptor 的这个实现,我在一个新的 spring 应用程序上进行了测试并工作了。

问题是,我似乎无法让它在我需要的 spring 应用程序上运行。

@Configuration
public class TestMethodConfig {

@Autowired
private TestService testService;


  @Bean
  @Primary
  public ProxyFactoryBean testProxyFactoryBean() {
    ProxyFactoryBean testProxyFactoryBean = new ProxyFactoryBean();
    testProxyFactoryBean.setTarget(testService);
    testProxyFactoryBean.setInterceptorNames("testMethodInterceptor");
    return testProxyFactoryBean;
  }
}

@Service
public class TestServiceImpl implements TestService{
  @Override
  public void testMethod(String test) {
    System.out.println("testService String");
  }
}

public interface TestService{
  void testMethod(String test);
}

@RestController
public class Controller {
  @Autowired
  private TestService testProxyFactoryBean;

  @GetMapping(value = "/test")
  public void test(){
    testProxyFactoryBean.testMethod("valor");
  }
}

@Component
public class TestMethodInterceptor implements MethodInterceptor {

  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    System.out.println("before method");
    System.out.println("invocation: " +      Arrays.toString(invocation.getArguments()));
    Object retVal = invocation.proceed();
    System.out.println("after method");
    return retVal;
  }
}

我使用Spring Actuator检查bean关系,我发现Controller上的@Autowired TestService应该被分配给testProxyFactoryBean,但它被分配给TestServiceImpl bean,所以我相信创建代理有问题。

testProxyFactoryBean 是自动装配到 testServiceImpl 而不是 testProxyFactoryBean

4

1 回答 1

1

简而言之

我不知道它是如何/为什么是:

在一个新的春季应用程序上并工作。

但:

我似乎无法让它在我需要的 spring 应用程序上运行。

..可能可以修复!

使其一致

或者:

@Configuration
public class TestMethodConfig {

  @Autowired
  private TestService testService;
}
...
// !!
public class TestServiceImpl implements TestService{
  @Override
  public void testMethod(String test) {
    System.out.println("testService String");
  }
}
...
@Service // !!!
public interface TestService{
  void testMethod(String test);
}
...
@RestController
public class Controller {
  @Autowired
  private TestService testProxyFactoryBean;
  ...

或:实施!(始终使用 Interface 和 Impl!)


详细地

6.4. 使用 ProxyFactoryBean 创建 AOP 代理

尤其是 代理接口

因此,在“影响最小”(和 java 配置)的情况下,它应该是:

@Configuration
public class TestMethodConfig {

  // !!! Impl from component-scan (@Service), NOT interface:
  @Autowired
  private TestServiceImpl testServiceImpl; // or define custom, or "inline"...

  @Bean
  @Primary // only if you need it, better would be: distinct!
  public ProxyFactoryBean testProxyFactoryBean() {
    ProxyFactoryBean testProxyFactoryBean = new ProxyFactoryBean();
     // !!! set proxyInterface as documented:
    testProxyFactoryBean.setProxyInterface(TestService.class);
    testProxyFactoryBean.setTarget(testServiceImpl);
    testProxyFactoryBean.setInterceptorNames("testMethodInterceptor");
    // ...
    return testProxyFactoryBean;
  }
}

..请享用!;)

于 2021-12-21T19:48:23.830 回答