Java 为来自超类的字段限定Spring依赖项注入

Java 为来自超类的字段限定Spring依赖项注入,java,spring,dependency-injection,inversion-of-control,Java,Spring,Dependency Injection,Inversion Of Control,如何在实现类中注入webServiceTemplate 我的例子是: public abstract class AbstractConnector { protected WebServiceTemplate webServiceTemplate; protected Object send(Object message) { return webServiceTemplate.marshalSendAndReceive(); } } 在我的具体实

如何在实现类中注入webServiceTemplate

我的例子是:

public abstract class AbstractConnector {

    protected WebServiceTemplate webServiceTemplate;

    protected Object send(Object message) {
        return webServiceTemplate.marshalSendAndReceive();

   }
}

在我的具体实现中,我想这样设置我的webServiceTemplate

public class MyConnector extends AbstractConnector {

   @Resource(name = "myWebService")
   private WebServiceTemplate webServiceTemplate;
}

但这不好。如果我调用send,那么我将获得NPE,因为webServiceTemplate为null。如何在send方法中可以访问的实现中设置此依赖关系?

最好尽可能避免字段注入,这就是其中的一个例子。构造函数注入使这变得简单:

public abstract class AbstractConnector {
    private final WebServiceTemplate webServiceTemplate;

    protected AbstractConnector(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
    }
}

@Service
public class MyConnector extends AbstractConnector {

    @Inject // or @Autowired
    public MyConnector(@Qualifier("myWebService") WebServiceTemplate webServiceTemplate) {
        super(webServiceTemplate);
    }
}

最好尽可能避免现场注入,这就是原因之一。构造函数注入使这变得简单:

public abstract class AbstractConnector {
    private final WebServiceTemplate webServiceTemplate;

    protected AbstractConnector(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
    }
}

@Service
public class MyConnector extends AbstractConnector {

    @Inject // or @Autowired
    public MyConnector(@Qualifier("myWebService") WebServiceTemplate webServiceTemplate) {
        super(webServiceTemplate);
    }
}
您可以使用方法查找:

您可以使用抽象类:

public abstract class AbstractConnector 
{

private abstract WebServiceTemplate getWebServiceTemplate();

protected Object send(Object message) 
{
    return getWebServiceTemplate().marshalSendAndReceive();
}
您的配置:

   <bean id="webServiceTemplate" scope="prototype" class="com.example.WebServiceTemplate" />
   <bean id="connector" class="com.example.AbstractConnector"
        <lookup-method name="webServiceTemplate" bean="webServiceTemplate" />
    </bean>
如果调用方法getWebServiceTemplate,Spring将连接抽象类以返回新的webServiceTemplate。

您可以使用方法查找:

您可以使用抽象类:

public abstract class AbstractConnector 
{

private abstract WebServiceTemplate getWebServiceTemplate();

protected Object send(Object message) 
{
    return getWebServiceTemplate().marshalSendAndReceive();
}
您的配置:

   <bean id="webServiceTemplate" scope="prototype" class="com.example.WebServiceTemplate" />
   <bean id="connector" class="com.example.AbstractConnector"
        <lookup-method name="webServiceTemplate" bean="webServiceTemplate" />
    </bean>

如果调用getWebServiceTemplate方法,Spring将连接您的抽象类以返回一个新的webServiceTemplate。

我不明白为什么在这里字段注入会变得不那么简单:

public abstract class AbstractConnector {
    protected WebServiceTemplate webServiceTemplate;

    public void setWebServiceTemplate(WebServiceTemplate template) {
        this.webServiceTemplate = template;
    }
}

public class MyConnector extends AbstractConnector {

    @Autowired("myWebService")
    @Override
    public void setWebServiceTemplate(WebServiceTemplate template) {
        super.setWebServiceTemplate(template);
    }
}

我不明白为什么现场注入会变得不那么简单:

public abstract class AbstractConnector {
    protected WebServiceTemplate webServiceTemplate;

    public void setWebServiceTemplate(WebServiceTemplate template) {
        this.webServiceTemplate = template;
    }
}

public class MyConnector extends AbstractConnector {

    @Autowired("myWebService")
    @Override
    public void setWebServiceTemplate(WebServiceTemplate template) {
        super.setWebServiceTemplate(template);
    }
}

很好的解决方案。但是,如果您的抽象连接是一个holder类,它使用了holding对象,或者以后您想将其作为一个单例使用,那么这种方法将失败。我删除了我的答案,因为这个答案是相同的,但注释更好。不要拖延时间,如果你的用例很简单,请保持代码简单,避免xml配置。@Hannes不清楚你所建议的edge case是什么意思。假设你的holder对象是一个只能读取一次的流。要重用holder,您总是需要holder的一个新实例来创建holding对象的一个新实例。这是一个很好的解决方案。但是,如果您的抽象连接是一个holder类,它使用了holding对象,或者以后您想将其作为一个单例使用,那么这种方法将失败。我删除了我的答案,因为这个答案是相同的,但注释更好。不要拖延时间,如果你的用例很简单,请保持代码简单,避免xml配置。@Hannes不清楚你所建议的edge case是什么意思。假设你的holder对象是一个只能读取一次的流。要重用holder,您始终需要holder的新实例来创建holding对象的新实例。