7

在一个非常大的遗留应用程序中,我有实现这些接口的接口和类。

接口是基于类生成的,因此签名相同(除了接口在顶部添加了另一个异常)并且名称相似(因此很容易从接口名称中找到类名)。

为了获得接口的实现,我们进行了一系列处理和记录调用,但基本上用于java.lang.reflect.Proxy委托给类。简化后看起来像这样:

// This will create a proxy and invoke handler that calls HelloWorld.doSomething
HelloWorldInterface i = MyProxyUtil.getInstance(HelloWorldInterface.class);
i.doSomething();

public interface HelloWorldInterface {
    public void doSomething() throws Exception;  
}

public class HelloWorld {
    public void doSomething() {
     //something
    }
}

是否可以使用 Spring 注释处理来处理@Autowire所有类型的字段*Interface并使用 springMyProxyUtil.getInstance(*Interface.class)来注入实现?

这样

@Autowire HelloWorldInterface a;

HelloWorldInterface b = MyProxyUtil.getInstance(HelloWorldInterface.class);

@Autowire AnotherInterface c;

AnotherInterface d = MyProxyUtil.getInstance(AnotherInterface.class);


a == b
c == d
4

2 回答 2

11

是的,您需要实现一个 AutowireCandidateResolver.

例如:

public class ProxyAutowiredCandidateResolver extends SimpleAutowireCandidateResolver {

    @Override
    public Object getSuggestedValue(DependencyDescriptor descriptor) {
        String dependencyClassName = descriptor.getDependencyType().getSimpleName();
        if (dependencyClassName.endsWith("Interface")) {
            return MyProxyUtil.getInstance(descriptor.getDependencyType());
        }

        return super.getSuggestedValue(descriptor);
    }

}

您可以使用 aBeanFactoryPostProcessor在应用程序上下文中对其进行配置:

public class AutowireCandidateResolverConfigurer implements BeanFactoryPostProcessor {

    private AutowireCandidateResolver autowireCandidateResolver;

    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory beanFactory) throws BeansException {
        DefaultListableBeanFactory  bf = (DefaultListableBeanFactory) beanFactory;
        bf.setAutowireCandidateResolver(autowireCandidateResolver);


    }

    public AutowireCandidateResolver getAutowireCandidateResolver() {
        return autowireCandidateResolver;
    }

    public void setAutowireCandidateResolver(

            AutowireCandidateResolver autowireCandidateResolver) {
        this.autowireCandidateResolver = autowireCandidateResolver;
    }

}

<bean id="autowireCandidateResolverConfigurer" class="AutowireCandidateResolverConfigurer">
        <property name="autowireCandidateResolver">
            <bean class="ProxyAutowiredCandidateResolver" />
        </property>
</bean>
于 2013-07-16T22:31:53.077 回答
1

如果我没看错,您应该能够在 JavaConfig @Configuration 注释类中定义它们,然后在其他地方使用它们。

从文档(Spring):

@Configuration
public class AppConfig {
  @Bean
  public MyService myService() {
      return new MyServiceImpl();
  }
}

你可以做类似的事情:

@Configuration
public class InterfaceConfig {
  @Bean
  public HelloWorldInterface helloWorldInterface() {
      return MyProxyUtil.getInstance(HelloWorldInterface.class);
  }
}

那时,只要需要该 bean,Spring 就会使用该定义。

您必须以某种方式链接@Configuration 类(类路径扫描、以编程方式等),但这取决于您如何设置应用程序上下文。

我认为这应该有效。我已经使用了很多 JavaConfig,但从来没有像这样使用过。但这似乎是合理的。

于 2013-07-16T21:53:24.933 回答