Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring:委托给自定义代理包装器进行接口注入_Java_Spring_Annotations_Aop_Factory - Fatal编程技术网

Java Spring:委托给自定义代理包装器进行接口注入

Java Spring:委托给自定义代理包装器进行接口注入,java,spring,annotations,aop,factory,Java,Spring,Annotations,Aop,Factory,在一个非常大的遗留应用程序中,我有一些接口和类,它们不实现这些接口 接口是基于类生成的,因此签名是相同的(除了接口在顶部添加了另一个异常),并且名称是相似的(因此很容易从接口名称中找到类名) 为了得到接口的实现,我们进行了大量的处理和日志调用,但基本上使用java.lang.reflect.Proxy来委托给类。它看起来是这样的: // This will create a proxy and invoke handler that calls HelloWorld.doSomething He

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

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

为了得到接口的实现,我们进行了大量的处理和日志调用,但基本上使用
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
所有类型为
*接口的字段
,并让Spring使用
MyProxyUtil.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

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

从文档()中:

你可以做类似的事情:

@Configuration
public class InterfaceConfig {
  @Bean
  public HelloWorldInterface helloWorldInterface() {
      return MyProxyUtil.getInstance(HelloWorldInterface.class);
  }
}
在这一点上,Spring将在需要bean时使用该定义

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


我认为这应该行得通。我经常使用JavaConfig,但从来没有像这样使用过。但这似乎是合理的。

是的,您需要实现一个
自动解算器

例如:

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);
    }

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

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>
公共类AutowireCandidateResolverConfigure实现BeanFactoryPostProcessor{
专用Autowire CandidateResolver Autowire CandidateResolver;
公共无效后处理BeanFactory(
ConfigurableListableBeanFactory(beanFactory)引发BeanException{
DefaultListableBeanFactory bf=(DefaultListableBeanFactory)beanFactory;
bf.setAutowireCandidateResolver(autowireCandidateResolver);
}
公共AutowireCandidateResolver getAutowireCandidateResolver(){
返回自动线解算器;
}
公共无效设置自动线解算器(
AutowireCandidateResolver(AutowireCandidateResolver){
this.autowireCandidateResolver=autowireCandidateResolver;
}
}

在配置中定义这些bean中的每一个(有数百个)对我来说并不实际。相反,我正在寻找一种方法,通过MyProxyUtil解析名称以接口结尾的所有接口。我没有理解这一部分。如果它都是遗留的,那么编写一个脚本一次性生成代码就不难了。虽然Jose的回答听起来很有趣,但我对此并不熟悉。代理是否已经由spring管理?您是否正在尝试对它们执行任何需要spring管理的操作?抱歉,我很难弄清楚您是如何实际配置它以供使用的?我将向我的applicationContext.xml中添加什么?@casenelson您可以使用
BeanFactoryPostprocessor
配置
AutowireCandidateResolver
使用解决方案注入环境时出现问题->@MariuszS在配置类中直接注册BFPP时出现问题。因为必须实例化配置类才能创建BFPP,所以在注册BPP之前,由于实例化发生得太早,所以跳过了bean后处理。您可以使用静态方法注册BFPP以避免问题。有关更多信息,请参阅。感谢提供有关
静态
的提示!
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>