Spring接口注入示例
Posted
技术标签:
【中文标题】Spring接口注入示例【英文标题】:Spring interface injection example 【发布时间】:2012-05-02 03:26:48 【问题描述】:到目前为止,还没有人能够在 Spring Framework 中提供一个正确的接口注入示例。
Martin Fowler 的文章不适用于凡人,其他所有内容都只是以非常混乱的方式定位的文字。我浏览了 30 篇文章,人们要么告诉“Spring 不直接支持接口注入”(“而且因为我不知道我将如何仅描述 setter 和构造函数注入”)或者“我将讨论它”在我的其他线程中”,或者下面很少有 cmets 说这是错误的例子。我不要求解释,例如我BEG。
有三种类型的注入:构造器、设置器和接口。 Spring 不直接支持最新的(正如我观察到的人们所说的那样)。那么具体是怎么做的呢?
谢谢,
【问题讨论】:
您知道,除了“不了解该主题”之外,还可能出于其他原因投反对票。 具体来说,你想要一个例子吗?为您的问题定义“接口注入”。 我猜投反对票是为了回应您的第一段咆哮,而且您的实际问题含糊不清,很容易简化为“有人可以给出 Spring 接口注入的示例吗?我有搜索了几个站点,但还没有找到一个。” (当然,假设这是你的问题)如果你发布你读过的文章也可能会有所帮助,以便人们更好地了解你已经看过的内容。 除了来自@NimChimpsky 的答案(在 Spring 中称为 AutoWiring 并通过 Annotations 或 XML 得到支持),还有一个 SO 问题,其中包含大量关于该主题的资源:@987654321@跨度> @Aubergine 我问的是在这个问题的上下文中,接口注入对你来说是什么样的——the Fowler article 对我来说似乎是正常的注入,但通过接口而不是类。如果您正处于撰写论文的阶段,那么 Fowler 的文章似乎应该非常直截了当——它比有关该主题的大多数学术论文更容易阅读,除非您在某种意义上使用“论文”而不是“我正在完成我的博士学位”。 如果将 bsc 最终项目称为论文是冒犯的,我会纠正自己。 :-) 最初我虽然接口注入是当你几乎使用设置器和构造器但提供接口时。下面的例子似乎是同样的混淆,或者我们是正确的。具体来说,这是我唯一难以理解的 Martin Fowler 文章。 【参考方案1】:根据Variants of DI in spring
DI 存在两种主要的变体,基于构造函数的依赖注入和基于 Setter 的依赖注入。
另请参阅Interface injection is not implemented in Spring 明确说明。
所以只有两种 DI 变体。因此,如果文档没有说明接口注入,很明显它不存在。那些认为接口注入是通过在接口中提供setter方法来完成的人回答我:
-
为什么 spring ref doc 没有提到接口注入?
为什么不能通过提供setter方法接口注入NOT被认为是setter注入本身。为什么要在引入接口不影响任何东西时为此创建特殊术语,我的意思是它仍然以相同的方式配置。如果它们不同,那么如何通过查看配置找到它。在配置中并没有看到实际配置的类实现某些接口的 impl 不应该是透明的吗?
就像Instantiation using an instance factory method和Instantiation using an static factory method一样,一些bean属性应该明确接口注入?
【讨论】:
在我自己花了相当长的时间解决这个问题之后,我相信 nanosoft 花了足够的精力来反驳其他答案。至少没有证据或示例不会混淆在 Spring IoC 中使用接口和接口注入的 setter/constructor DI。在研究和洞察方面再次做得很好。【参考方案2】:通过接口注入,接口明确定义了可以设置依赖项的点:
interface InjectPerson
public void injectHere(Person p);
class Company implements InjectPerson
Person injectedPerson;
public void injectHere(Person p)
this.injectedPerson = p;
【讨论】:
不,注射是在别处完成的。这只是说“一家公司应该能够让一个人注射”。 解决方法不是接口注入-springbyexample.org/examples/… @nanosoft 谢谢,我赞成您的回答,但您提供的资源仍然可以追溯到 Spring 2.0 asfaik。现在我们有了更多的东西,即使当时还没有 Spring Boot 的魔力,我明白为什么他们不能仅仅实现它。我想我将不得不通过 Jira 票直接询问 Spring 家伙,只是出于好奇。 @Aubergine - docs.spring.io/spring/docs/current/spring-framework-reference/… 属于春季 4.1.7.RELEASE。您可以通过滚动到页面底部并单击主页链接来检查。在新页面的顶部,您将看到版本 4.1.7.RELEASE。在那个参考文档中,没有提到我在回答中提到的接口注入。【参考方案3】:您好,我尝试了一种非常简单的方法,可以澄清您的答案。
以下是我使用两个接口和两个 bean 类构建的代码。
第一个名为 Job 的接口。
public interface Job
public void setmyJob(String myJob);
public String getmyJob();
还有一个类来实现这个接口,名称为 MyJob
public class MyJob implements Job
public String myJob;
public MyJob()
System.out.println("From MyJob default Constructor and the ID= "+this);
public void setmyJob(String myJob)
this.myJob=myJob;
public String getmyJob()
return myJob;
在下一步中,我创建了另一个名为 Service 的接口
public interface Service
public void setJob(Job job);
public Job getJob();
然后另一个类来实现这个服务接口。
public class MyService implements Service
public Job job;
public void setJob(Job job)
this.job=job;
System.out.println("Hello from Myservice: Job ID="+job);
public Job getJob()
return job;
然后我用main函数在主类上创建并编写代码如下:
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApplication
public static void main(String...a)
BeanFactory beanfactory=new ClassPathXmlApplicationContext("Beans.xml");
MyService myservice=(MyService)beanfactory.getBean("myservice");
System.out.println("Before print");
System.out.println(myservice.getJob().getmyJob());
在我的 Beans.xml 文件中,我提到了如下代码并且它有效。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="myjob" class="MyJob">
<property name="myJob" value="My First String"/>
</bean>
<bean id="myservice" class="MyService">
<property name="job" ref="myjob"/>
</bean>
</beans>
我也参考了另一个在线教程,然后得到了这种解决方案。如果您对此代码有任何问题,请告诉我。它对我有用。
【讨论】:
你能告诉我你从哪里得到的在线教程吗? 那么它与 setter 注入有何不同...?您在 MyService 类中有属性作业,您本质上是通过 setter 方法注入的,因此是 setter 注入......我相信只是引入接口没有任何区别...... Spring 中没有实现接口注入 - springbyexample.org/examples/… 在给定的链接中清楚地写着“这是一种不同类型的 DI,涉及映射项目以注入特定接口。”这意味着我们需要指定为某个接口注入哪个具体实现。我做过类似的事情。注入具体类可能是一种错误的方式,但现在您在类中拥有的是一个包含其具体类引用的接口。【参考方案4】:依赖注入有3种类型:-
1. Constructor Injection(E.g Pico Container, Spring supports it).
2. Setter Injection(E.g Spring supports it).
3. Interface Injection(E.g Avalon, Spring does not support it).
Spring 仅支持基于构造函数和设置器的注入。 看起来您对不同的类型(3)和弹簧支持的类型(其中的 2 个)感到困惑。
【讨论】:
【参考方案5】:我认为,关于接口注入的混淆是由于误解了“接口注入”一词的实际含义。在我的理解中,接口注入描述了 bean 竞争者向 bean 注入新接口的能力,不管这个 bean 的类定义没有实现它。
这里展示的所有示例都展示了如何从具体类中创建一个 bean,然后如何将它注入另一个 bean。事实上,在所有情况下,bean 都被注入到定义为接口的字段中,这并不重要——所有操作都是使用由具体实例创建的 bean 完成的。
我还可以提供另一个吸引人的例子:
package creditCards;
interface PaymentCard
Boolean isDebitAllowed();
<bean id="card" class="creditCards.PaymentCard">
<lookup-method name="isDebitAllowed" bean="boolValue"/>
</bean>
<bean id="boolValue" class="java.lang.Boolean">
<constructor-arg type="boolean" value="true"/>
</bean>
正如您在此处看到的,甚至可以从接口创建 bean!尽管如此,它不是接口注入,因为 IoC 竞争者自己初始化了这个 bean 的实例。换句话说,card
bean 是一个初始化的对象,而不是一个接口,这使得该问题的选择答案是正确的。
【讨论】:
【参考方案6】:我想有人回答了你的问题here 我也不知道接口注入是什么,直到我从“Pro Spring MVC with web flow book”中阅读了这个声明
"请注意,Spring 框架不支持基于接口的依赖注入。这个 意味着我们需要指定为某个接口注入哪个具体实现。”
【讨论】:
【参考方案7】:请查看下面的 iterface 注入示例。
有一个形状接口和 2 个具体的类来实现形状,即正方形和矩形。
界面
package di.interfaceinjection;
public interface Shape
public String shapeName();
public void displayName();
2 实现类
package di.interfaceinjection;
public class Square implements Shape
@Override
public String shapeName()
return "Square";
@Override
public void displayName()
System.out.println("Square");
package di.interfaceinjection;
public class Rectangle implements Shape
@Override
public String shapeName()
return "Rectangle";
@Override
public void displayName()
System.out.println("Rectangle");
现在,我们有一个设置形状的类。
public class ShapeSetter
private Shape shape;
public Shape getShape()
return shape;
public void setShape(Shape shape)
this.shape = shape;
最后是配置
<bean id="shape1" class="di.interfaceinjection.ShapeSetter">
<property name="shape" ref="square"></property>
</bean>
<bean id="shape2" class="di.interfaceinjection.ShapeSetter">
<property name="shape" ref="rectangle"></property>
</bean>
<bean id="square" class="di.interfaceinjection.Square"></bean>
<bean id="rectangle" class="di.interfaceinjection.Rectangle"></bean>
这里,
我们正在注入不同的形状。
package di.interfaceinjection;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class InterfaceInjeection
/**
* @param args
*/
public static void main(String[] args)
ApplicationContext appContext = new ClassPathXmlApplicationContext("intro.xml");
ShapeSetter shape = (ShapeSetter)appContext.getBean("shape2");
shape.getShape().displayName();
【讨论】:
以上是关于Spring接口注入示例的主要内容,如果未能解决你的问题,请参考以下文章