Spring Framework到底是做什么用的?[关闭]


623

我听说过很多有关Spring的信息,人们在网络上都说Spring是Web开发的良好框架。Spring Framework到底是做什么用的?


10
我知道这个问题涉及面很广,但是我确实认为,在这种非常特殊的情况下,这个问题对于junion开发人员非常重要,因为他们经常被认为是非常受欢迎的人们谈论Spring,甚至不需要说出什么。是的。毕竟,举起你的手,如果你从来没有听说过的Instagram,什么它的目的是....(自白:我从来没有使用过的Insta)
USR-本地ΕΨΗΕΛΩΝ

2
这个问题是在10年前提出的,当时Spring的所有子项目(例如Spring Boot,Spring Data,Spring Rest等)都比现在要小一些。实际上,这就是为什么它在一年前就关闭的原因这个问题的广泛性。当我问这个问题时,我只是想了解DI以及为什么需要它。
Maksim

Answers:


713

基本上,Spring是一个框架 这是一种允许构建高度分离的系统的模式。

问题

例如,假设您需要列出系统的用户,从而声明一个名为的接口UserLister

public interface UserLister {
    List<User> getUsers();
}

也许是一个访问数据库以获取所有用户的实现:

public class UserListerDB implements UserLister {
    public List<User> getUsers() {
        // DB access code here
    }
}

在您看来,您需要访问一个实例(仅作为示例,请记住):

public class SomeView {
    private UserLister userLister;

    public void render() {
        List<User> users = userLister.getUsers();
        view.render(users);
    }
}

注意上面的代码没有初始化变量userLister。我们应该做什么?如果我像这样显式实例化该对象:

UserLister userLister = new UserListerDB();

...我会将视图与实现访问数据库的类的实现结合在一起。如果我想从数据库实现切换到另一个从逗号分隔的文件中获取用户列表的实现该怎么办(请记住,这是一个示例)?在这种情况下,我将再次进入我的代码并将上面的行更改为:

UserLister userLister = new UserListerCommaSeparatedFile();

这样的小程序没有问题,但是...在具有数百个视图和类似数量的业务类的程序中会发生什么?维护成了一场噩梦!

Spring(依赖注入)方法

什么春天确实是来连线通过使用XML文件或注解,这样所有的对象实例化和春天初始化和班达注射在适当的地方(Servlet的Web框架,业务类,DAO的,等,等,等...)。

回到Spring中的示例,我们只需要为该userLister字段设置一个setter,并拥有一个像这样的XML文件:

<bean id="userLister" class="UserListerDB" />

<bean class="SomeView">
    <property name="userLister" ref="userLister" />
</bean>

或更简单地使用以下注释在我们的视图类中归档@Inject

@Inject
private UserLister userLister;

当视图被创建这样奇迹般地将有一个UserLister准备工作。

List<User> users = userLister.getUsers();  // This will actually work
                                           // without adding any line of code

太好了!是不是

  • 如果要使用UserLister接口的其他实现怎么办?只需更改XML。
  • 如果尚未UserLister准备好实施该怎么办?对时态模拟实现进行编程,UserLister并简化视图的开发。
  • 如果我不想再使用Spring怎么办?只是不要使用它!您的应用程序未与其耦合。控制反转状态:“应用程序控制框架,而不是框架控制应用程序”。

依赖注入还有其他选择,在我看来,Spring除了简单,优雅和稳定外,还让Spring如此出名是因为SpringSource的人已经编写了许多POJO,这些POJO有助于将Spring与许多其他通用框架集成在一起。侵入您的应用程序。而且,Spring有几个不错的子项目,例如Spring MVC,Spring WebFlow,Spring Security以及大量的etceteras列表。

希望这可以帮助。无论如何,我鼓励您阅读Martin Fowler关于依赖注入和控制反转的文章,因为他比我做得更好。了解基本看一看之后Spring文档,在我看来,这 曾经是最好的春季书永远。


148
必须更改一行代码和一行XML有什么区别?工作和维护工作完全相同,甚至更糟,因为外部xml文件无疑会增加复杂性?抱歉,但是我不明白,我什么都看不到。如果我缺少什么,请填写。
弗雷德

23
@fred-想象您正在进行单元测试。没有依赖关系注入(DI可以与批注或XML结合使用),您将无法正确测试,因为您无法模拟依赖关系。
Petar Minchev 2011年

18
@fred-在XML中定义所有注入确实没有任何意义。这是一个庞大的维护费用。因此,EJB引入了注入点注释的概念。那些要简单得多,并且将注入默认实例(对于单元测试,可以更改一次)。效果很好,Spring现在复制了这种方法。请注意,如果需要(但仅在确实需要时),注释仍可以由EJB中的XML覆盖。
Mike Braun 2012年

36
或者,您知道使用工厂静态方法。更改工厂的返回类型,现在所有使用该返回值的类都将更改。现在不再需要Presto Spring ...
Qix-蒙尼卡(Monica)错

16
@mmcrae我宁愿在IDE中进行一次重构调用,也不想编写XML。
Qix-蒙尼卡(Monica)

63

Spring 包含如Skaffman正确指出的)MVC框架。简而言之,这是我的投入。Spring支持服务层,Web层和业务层的隔离,但是真正做到最好的是对象的“注入”。因此,以一个示例进行解释,请考虑以下示例:

public interface FourWheel
{
   public void drive();
}

public class Sedan implements FourWheel
{
   public void drive()
   {
      //drive gracefully
   }
}

public class SUV implements FourWheel
{
   public void drive()
   {
      //Rule the rough terrain
   }
}

现在,在您的代码中,有一个名为RoadTrip的类,如下所示

public class RoadTrip
{
    private FourWheel myCarForTrip;
}

现在,无论何时您想要一个Trip实例;有时您可能想要SUV初始化FourWheel,有时您可能想要轿车。这实际上取决于您根据特定情况想要的内容。

要解决此问题,您需要将工厂模式用作创建模式。工厂返回正确实例的位置。因此,最终您将获得大量粘合代码,仅用于正确实例化对象。如果没有粘合代码,Spring会最好地执行粘合代码的工作。您以XML声明映射,它会自动初始化对象。在实例中使用单例架构也很有用,这有助于优化内存使用。

这也称为控制反转。其他实现此目的的框架是Google guice,Pico容器等。

除此之外,Spring还具有验证框架,与JDBC,iBatis和Hibernate(以及更多)协作,对DAO层提供了广泛的支持。提供对数据库事务的出色事务控制。

Spring可以在诸如“ Pro Spring”之类的好书中阅读,还有更多内容。

跟随URL也可能有帮助。
http://static.springframework.org/docs/Spring-MVC-step-by-step/
http://en.wikipedia.org/wiki/Spring_Framework
http://www.theserverside.com/tt/articles/article .tss?l = SpringFramework


5
Spring 包含一个MVC框架。但这还远远不止这些。
skaffman 2009年

WebMVC不想过多地挑剔,它是Spring核心发行版的一部分。Webflow,RCP等不是。
skaffman

1
很好,我不知道您可以在Java中实例化类型为Interface的对象- 这是非法的 @skaffman帮助我理解此答案(请参见FourWheel的实例)
Jossie Calderon

47

过去,Spring是依赖注入框架(仅类似于GuicePicoContainer等),但如今,它是构建企业应用程序的完整解决方案。

spring依赖注入,当然,这仍然是spring的核心(您可以在这里查看其他好的答案),但是spring还有更多...

Spring现在有很多项目,每个项目都有一些子项目(http://spring.io/projects)。当某人谈论Spring时,您必须找出他正在谈论的Spring项目,是仅Spring核心(被称为Spring Framework),还是另一个Spring项目。

一些春季项目值得一提:

如果您需要为应用程序提供更多指定功能,则也可以在其中找到它:

  • Spring Batch 批处理框架旨在支持
    批处理应用程序的开发
  • Spring HATEOAS基于HATEOAS主体轻松创建REST API
  • Spring MobileSpring Andriod用于移动应用程序开发
  • Spring Shell 构建一个功能齐全的Shell(又名命令行)应用程序
  • 用于云应用程序的Spring CloudSpring Cloud Data Flow

那里还有一些小项目,例如spring-social-facebookhttp://projects.spring.io/spring-social-facebook/

您可以将spring用于Web开发,因为它具有Spring Framework项目中的Spring MVC模块。或者,您可以将spring与其他Web框架一起使用,例如struts2


1
我实际上希望看到Spring的mvc,data,jpa和其他部分可以选择不使用Spring的核心DI,而是将Dagger放在Spring的心脏中。
dlamblin

25

春天有什么用?我将很快回答这个问题,但首先,让我们再看一看胜利者雨果的例子。这不是一个很好的例子,因为它不能证明对新框架的需求。

public class BaseView {
  protected UserLister userLister;

  public BaseView() {
    userLister = new UserListerDB(); // only line of code that needs changing
  }
}

public class SomeView extends BaseView {
  public SomeView() {
    super();
  }

  public void render() {
    List<User> users = userLister.getUsers();
    view.render(users);
  }
}

做完了!因此,即使您有成百上千的视图,仍然像Spring XML方法一样只需要更改一行代码。但是更改一行代码仍然需要重新编译,而不是编辑XML。好吧,我挑剔的朋友,请使用Ant并删除脚本!

那么Spring的目的是什么?它用于:

  1. 追随者的盲人开发商
  2. 不想因为在Uni教授这样的框架而不想雇用研究生程序员的雇主
  3. 从不良的设计开始并需要拼凑的项目(如victor hugo的示例所示)

进一步阅读:http : //discuss.joelonsoftware.com/?joel.3.219431.12


11
除了沮丧,我想知道您的论点。我不知道您不能使用任何编程工具来产生不良设计。您的目标是使用框架可以使错误的代码做很多事情。这是普遍的事实,并非特定于Spring。否则有什么意义呢?您不认为有能力的开发人员可以充分利用Spring所提供的功能-特别是在他们使用框架的哪些工具时?至少我可以肯定地说,您并不意味着没有Spring开发人员听说过扩展类。但是,进一步的阅读很有趣。
sthzg

2
此外,您的示例之所以有效,是因为视图仅需要一个注入的服务(UserLister),但是如果视图需要多个服务,而不是在不同BaseView子对象之间共享,该怎么办?(幸运的是)Java中没有多重继承。
爱德华·伯特

@EdouardBerthe博览会要点。我的答案并不是试图忽视DI,它只是指出了公认的答案中显示的例子并不是最大的例子;您提出的方案很可能会更好地工作。我真正想说明的重点不是您不需要DI,而是不需要整个框架来完成它。
灰烬

19

简短地总结一下,我将说Spring是您应用程序中的“胶水”。它用于集成不同的框架和您自己的代码。


15

春天是三件事。

  1. Spring处理依赖注入,我建议您阅读Martin Fowler关于依赖注入的出色介绍。
  2. Spring要做的第二件事是以出色的方式包装优秀的Java库,以便在您的应用程序中使用。一个很好的例子,请参见Spring如何包装Task Executors和Quartz Scheduler。
  3. 第三,Spring提供了很多Web东西的实现,例如REST,MVC Web框架等等。他们认为,因为您在前两个中都使用Spring,也许您可​​以将其用于Web应用程序所需的一切。

问题在于,Spring DI确实经过深思熟虑,围绕其他事物的包装确实经过了深思熟虑,因为其他事物认为一切都已解决,而Spring恰好将其包装好。MVC和REST以及其他所有东西的Spring实现都做得不好(YMMV,恕我直言),但是有例外(Spring Security是炸弹)。因此,我倾向于将Spring用于DI及其出色的包装器,但更喜欢Web(我非常喜欢Tapestry),REST(Jersey确实很健壮)等其他东西。


9
YMMV,恕我直言-您的里程可能会有所不同,以我的拙见为那些不懂我这样缩写的人...
Sakamoto Kazuma 2015年

11

使用Spring在Web应用程序中可能想要的-

  • Spring MVC具有2.5+版本,允许您将POJO用作Controller类,这意味着您不必从任何特定框架进行扩展(如Struts或Spring 2.5之前的版本)。控制器类也很容易测试,这部分归功于依赖注入
  • 与Hibernate的Spring集成,在简化该ORM解决方案的工作方面做得很好(大多数情况下)
  • 将Spring用于Web应用程序使您可以在应用程序的所有级别上使用域对象-使用Hibernate映射的相同类是用作“表单bean”的类。从本质上讲,这将导致一个更强大的领域模型,部分原因是它将减少类的数量。
  • Spring表单标签使创建表单变得更加容易,而没有太多麻烦。

此外,Spring非常庞大-因此,您可能会对在Web应用程序中使用很多其他东西感兴趣,例如Spring AOP或Spring Security。但是上面列出的四件事描述了Web应用程序中使用的Spring的常见组件。


9

我看到两个部分:

  1. “ Spring到底是干什么的”->参见victor hugo接受的答案。
  2. “ [...] Spring是用于Web开发的良好框架”->人们说这是在谈论Spring MVC。Spring MVC是Spring的众多部分之一,并且是一个利用Spring的一般功能(如依赖注入)的Web框架。这是一个非常通用的框架,因为它是可配置的:您可以使用不同的数据库层(Hibernate,iBatis,纯JDBC),不同的视图层(JSP,Velocity,Freemarker ...)

请注意,您可以在Web应用程序中完美使用Spring,而无需使用Spring MVC。我会说大多数Java Web应用程序都这样做,而使用了诸如Wicket,Struts,Seam等其他Web框架。


8

Spring非常适合将类的实例粘合在一起。您知道,您的Hibernate类将始终需要数据源,Spring将它们连接在一起(并且也具有数据源的实现)。

您的数据访问对象将始终需要Hibernate访问,Spring会为您将Hibernate类连接到您的DAO中。

此外,Spring基本上为您提供了一堆库的可靠配置,并在其中为您应使用的库提供了指导。

春天确实是一个很棒的工具。(我不是在谈论Spring MVC,而只是在谈论基础框架)。


5

可接受的答案不涉及注释的使用,因为Spring引入了对各种配置注释的支持。

Spring(依赖注入)方法

还有另一种使用XML文件将类连接在一起的方法:注释。让我们用从接受答案的例子,并直接使用注释的一个类注册豆@Component@Service@Repository@Configuration

@Component
public class UserListerDB implements UserLister {
    public List<User> getUsers() {
        // DB access code here
    }
}

这样,在创建视图时,它会神奇地使UserLister就绪。

上面的语句是有效的,并且不需要任何XML文件使用,也不需要与其他注释@Autowired相关的实现发现并注入的注释。

@Autowired
private UserLister userLister;

使用@Bean注释上用来获取bean的实现注入的方法。


错误。您不能@Bean在课程级别使用注释。必须是一@Component@Service@Repository等休息是正确的。您可能还应该指出,只有在类路径中只有一个适合注入的候选类时,这种方式的自动装配接口才有效,否则,Spring应用程序错误。
Stefano L

@StefanoL:是的,你是对的。我不知道人们会忽略我的错误。感谢您的评论。
Nikolas

4

优点是依赖注入(DI)。这意味着将对象创建任务外包了。让我用一个例子来解释。

public interface Lunch
{
   public void eat();
}

public class Buffet implements Lunch
{
   public void eat()
   {
      // Eat as much as you can 
   }
}

public class Plated implements Lunch
{
   public void eat()
   {
      // Eat a limited portion
   }
}

现在在我的代码中,我有一个LunchDecide类,如下所示:

public class LunchDecide {
    private Lunch todaysLunch;
    public LunchDecide(){
        this.todaysLunch = new Buffet(); // choose Buffet -> eat as much as you want
        //this.todaysLunch = new Plated(); // choose Plated -> eat a limited portion 
    }
}

在上面的课程中,根据我们的心情,我们选择Buffet()或Plated()。但是,该系统紧密耦合。每当我们需要不同类型的Object时,我们都需要更改代码。在这种情况下,注释掉一行!想象一下,有50个不同的类别,供50个不同的人使用。真是一团糟。在这种情况下,我们需要解耦系统。让我们重写LunchDecide类。

public class LunchDecide {
    private Lunch todaysLunch;
    public LunchDecide(Lunch todaysLunch){
        this.todaysLunch = todaysLunch
        }
    }

注意,不是使用new关键字创建对象,而是将对午餐类型的对象的引用作为参数传递给构造函数。在这里,对象创建是外包的。可以使用Xml配置文件(旧版)或Java注释(现代版)连接此代码。无论哪种方式,都将在运行时期间决定要创建哪种类型的对象。Xml将对象注入到我们的代码中-我们的代码依赖于Xml来完成该工作。因此,依赖注入(DI)。DI不仅有助于使我们的系统松散耦合,而且由于可以模拟依赖关系,因此简化了单元测试的编写。最后但并非最不重要的一点是,DI简化了面向方面的编程(AOP),这导致了进一步的去耦和模块化的提高。还要注意,上面的DI是构造函数注入。


但是即使在使用Spring的情况下,我们仍然会定义bean。并且bean id将在代码中给出,不是吗?因此,如果明天更改bean,您仍然必须更改代码,不是吗?那有什么好处。
Arpan Buch '18

@ArpanBuch我认为spring的好处是您可以选择一个不同的实现而无需重新编译任何代码(只要其他实现已经存在)。我是一个初学者,所以我可能是错的。
byxor19

4
  • 与J2EE相比,Spring是一个轻量级且灵活的框架。
  • 弹簧容器充当控件的反转。
  • Spring使用AOP,即代理和Singleton,Factory和Template Method设计模式。
  • 分层体系结构:关注点和可重用层的分离以及易于维护。

在此处输入图片说明


1
Spring Framework help you with several things like, don't reinvent the wheel. you can connect very easily with some database just using Spring Data, or create schedule tasks like CronJob or Windows Task. amazing !
tomj0101 '17

3

Spring是Enterprise JavaBeans(EJB)技术的很好的替代品。它还具有Web框架和Web服务框架组件。


1
我可以纠正吗?(可怕的)EJB 2的替代品……似乎“新EJB”(部分是JPA 2,等等)已经越来越令人接受。春季部分“一种EJB”的“欢乐时光”似乎已经过去。广告2015年
Jacek Cz

1

Spring最初是一个非常简单的依赖项注入系统。现在它很大了,里面有一切(众所周知的厨房水槽除外)。

但是不要担心,它是模块化的,因此您可以只使用所需的部件。

要查看一切从哪里开始,请尝试:

http://www.amazon.com/Expert-One-Design-Development-Programmer/dp/0764543857/ref=sr_1_1?ie=UTF8&s=books&qid=1246374863&sr=1-1

它可能很旧,但是很不错。

对于这次专门专门针对Spring的另一本好书,请参阅:

http://www.amazon.com/Professional-Java-Development-Spring-Framework/dp/0764574833/ref=sr_1_2?ie=UTF8&s=books&qid=1246374863&sr=1-2

它还引用了Spring的旧版本,但是绝对值得一看。


1

Spring从一开始就是依赖注入,然后为几乎所有内容(包装JPA实现等)添加了包装王。

长话短说... Spring首选XML解决方案的大部分内容(XML脚本引擎... brrrr),因此对于DI来说,我使用Guice

好的库,但是随着depnedenciec的增长,例如Spring JDBC(也许是一个带有实名参数的Java jdbc解决方案)接下来是maven 4-5。

使用Spring MVC(“大春天”的一部分)进行Web开发...它是“基于请求”的框架,有一场“请求与组件”的圣战...由您决定


1
我相信现在Spring框架正在尝试从XML转移到注释和Java配置。
Maksim 2015年

0

过去,我从纯粹的技术角度考虑过Spring框架。

有了一些团队合作和开发企业Webapp的经验,我想说Spring可以通过以下方式更快地开发应用程序(Web应用程序)分离其各个元素(bean)。更快的开发使其如此受欢迎。Spring允许将构建(连接)应用程序的责任转移到Spring框架上。Spring框架的依赖项注入负责将各个bean连接/连接到一个正在运行的应用程序中。

这样,一旦定义了bean之间的接口,开发人员便可以更加专注于单个组件(bean)的开发。

这种应用程序的测试很容易-主要重点放在各个bean上。它们可以轻松地解耦和模拟,因此单元测试是快速而有效的。

Spring框架定义了多个专用Bean,例如@Controller@Restcontroller),@Repository@Component来实现Web目的。Spring与Maven一起提供了对开发人员直观的结构。团队合作既容易又快速,因为各个要素分开放置并且可以重复使用。


0

Spring框架绝对适合Web开发,并且更适合静态api服务。

由于它的依赖关系注入 以及与其他模块(如spring安全spring aopmvc框架微服务)的集成,因此对上述内容有好处

在任何应用程序中,最有可能需要安全性。
如果您打算构建需要长期维护的产品,那么您将需要利用Aop概念。

如果您的应用程序流量很大,从而增加了负载,则需要使用微服务概念。

Spring在一个平台上提供了所有这些功能。支持许多模块
最重要的是,spring是开源的并且是可扩展的框架,处处都有一个挂钩,可以在生命周期中集成自定义代码。

Spring Data是一个提供与您的项目集成的项目。


因此,弹簧几乎可以满足所有要求。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.