java - Spring框架到底是什么?


我听到很多关于Spring的信息 ,人们都在网上说Spring是一个很好的Web开发框架。 Spring框架到底是什么? 我如何将它用于我的Web-Java应用程序开发? 任何例子?


Answers



基本上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();

...我将这个视图与我的实现访问数据库的类相结合。 如果我想从DB实现切换到另一个从逗号分隔的文件中获取用户列表(请记住,这是一个例子)? 在这种情况下,我会再次去我的代码,并通过更改最后一行:

UserLister userLister = new UserListerCommaSeparatedFile();

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

Spring(依赖注入)方法

Spring所做的是通过使用XML文件连接类,这样所有对象都被Spring实例化和初始化,并被注入到正确的地方(Servlets,Web Frameworks,Business classes,DAO等等等等。 )。

回到Spring中的例子,我们只需要为userLister字段设置一个setter,并使用这样的XML:

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

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

这种方式当视图被创建时, 神奇地将有一个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,还有一些其他的等等。

希望这可以帮助。 无论如何,我鼓励你阅读Martin Fowler关于依赖注入和控制反转的文章 ,因为他比我更好。 在了解基础之后,看看Spring Documentation ,在我看来,它曾经是有史以来最好的Spring书籍。




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,或者有时你可能想要四门轿车。 这真的取决于你想要根据具体情况。

为了解决这个问题,你希望有一个工厂模式作为创建模式。 工厂返回正确的实例。 所以最终你会得到大量的胶水代码来正确地实例化对象。 春天没有胶水代码最好的胶水代码的工作。 您声明XML中的映射,并自动初始化对象。 它也使用单例体系结构的实例很多,这有助于优化内存使用情况。

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

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

春天还有很多东西可以在“Pro Spring”这样的好书中读到。

以下网址也可能有帮助。
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




什么是春天? 我很快就会回答这个问题,但首先让我们再来看一下维克托·胡戈的例子。 这不是一个很好的例子,因为它没有理由需要一个新的框架。

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,你说? 那么我的挑剔的朋友,用蚂蚁和脚本!

那Spring是什么? 这是为了:

  1. 盲人开发者遵循这个群体
  2. 雇主谁也不想雇用研究生程序员,因为他们不在Uni教这样的框架
  3. 以糟糕的设计开始并需要拼凑的项目(如victor hugo的例子所示)

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




过去, Spring只是一个像( GuicePicoContainer ,...)这样的依赖注入框架工作,但现在一天它是一个为您构建企业应用程序的总体解决方案。

春天依赖注入,当然是春天的心脏仍然存在(你可以在这里回顾其他好的答案),但是从春天还有更多...

Spring现在有很多项目,每个项目都有一些子项目( http://spring.io/projects )。 当有人谈到春天的时候,你一定要搞清楚他在说什么春天的项目 ,是春天的核心, 春天的春天 ,还是春天的项目。

一些值得一提的春季项目是:

如果您的应用程序需要更多的指定功能,您可能也会发现它:

  • 弹簧批量框架设计,使开发
    批量应用
  • spring HATEOAS基于HATEOAS主体轻松创建REST API
  • 用于移动应用开发的spring mobilespring andriod
  • 弹簧壳构建一个全功能的shell(aka命令行)应用程序
  • 春天云春天云彩数据流为云彩应用

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

您可以使用spring来进行Web开发,因为它具有Spring MVC模块,这是Spring MVC 框架项目的一部分。 或者你可以使用其他web框架的工作,如struts2




总结很简短,我会说Spring是你应用程序中的“胶水”。 它被用来集成不同的框架和你自己的代码。




春天是三件事。

  1. Spring处理依赖注入,我建议你阅读Martin Fowler关于依赖注入的优秀介绍。
  2. Spring做的第二件事就是用优雅的方式将优秀的Java库封装在应用程序中。 看一个很好的例子,看看Spring如何包装Task Executors和Quartz Scheduler。
  3. 第三,Spring提供了大量的REST,MVC Web框架等网络实现。 他们认为,因为你使用Spring的前两个,也许你可以使用它的一切你的web应用程序需要。

问题在于,Spring DI是真的很好的想法,其他东西的包装真的很好的思考,其他的东西都想出来,Spring很好地包装它。 MVC和REST的Spring实现和其他所有的东西都没有完成(YMMV,IMHO),但是也有例外(Spring Security是da bomb)。 所以我倾向于使用DI的春天,它的酷包装,但喜欢其他东西的Web(我喜欢Tapestry很多),REST(泽西岛是非常强大的),等等。




使用Spring的Web应用程序可能需要什么 -

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

另外,Spring是巨大的 - 所以在Spring AOP或Spring Security等Web应用程序中,您可能会感兴趣的还有很多其他的东西。 但上面列出的四件事情描述了在Web应用程序中使用的Spring的常见组件。




我看到这两个部分:

  1. “春天到底是什么” - >见维克托·胡戈接受的答案。
  2. “Spring是一个很好的Web开发框架” - >人们说这是在谈论Spring MVC。 Spring MVC是Spring的许多部分之一,是一个使用Spring的一般特性的Web框架,就像依赖注入一样。 这是一个非常通用的框架,它是非常可配置的:您可以使用不同的数据库层(Hibernate,iBatis,普通的JDBC),不同的视图层(JSP,Velocity,Freemarker ...)

请注意,您可以在不使用Spring MVC的情况下,在Web应用程序中完美地使用Spring。 我会说大多数Java Web应用程序这样做,而使用像Wicket,Struts,煤层等其他Web框架...




Spring非常适合将类的实例粘合在一起。 你知道你的Hibernate类总是需要一个数据源,Spring把它们连接在一起(也有一个数据源的实现)。

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

此外,Spring基本上为您提供了一堆库的可靠配置,并在这方面为您提供了有关应该使用哪些库的指导。

Spring是一个非常棒的工具。 (我不是在谈论Spring MVC,只是基础框架)。







优点是依赖注入(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()。 但是这个系统是紧密结合的。 每次我们需要一个不同类型的对象,我们需要改变代码。 在这种情况下,注释掉一行! 想象一下,50个不同的人使用了50个不同的类。 这将是一个混乱的地狱。 在这种情况下,我们需要将系统解耦。 我们来重写LunchDecide类。

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

请注意,不是使用new关键字创建对象,而是将对Lunch Type的对象的引用作为参数传递给我们的构造函数。 这里,对象创建是外包的。 此代码可以使用Xml配置文件(传统)或Java注释(现代)连线。 无论哪种方式,决定哪种类型的对象将在运行时在那里完成。 一个对象将通过Xml注入到我们的代码中 - 我们的代码依赖于该作业的Xml。 因此,依赖注入(DI)。 DI不仅有助于使我们的系统松散耦合,还简化了单元测试的编写,因为它允许依赖性被嘲弄。 最后但并非最不重要的是,DI简化了面向方面编程(Aspect Oriented Programming,AOP),从而进一步解耦和增加了模块性。 另外请注意,上面的DI是构造器注入。 DI也可以通过Setter Injection来完成 - 同样的普通老式封装方法也是如此。




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

Spring(依赖注入)方法

还有另外一种方法可以使用XML文件连接类:注释。 让我们使用接受的答案中的示例,并使用唯一的注释@Bean直接在类中注册bean:

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

这样当视图被创建时,神奇的将会有一个UserLister准备好工作。

上面的语句是有效的,不需要任何XML文件的使用和接线另一个注释@Autowired ,找到一个相关的实现,并注入一点奖金。

@Autowired
private UserLister userLister;



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

它可能是旧的,但它是一本很好的书。

这次专门针对春天的另一本好书看到:

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的旧版本,但绝对值得一看。




Spring在开始时是依赖注入,然后为几乎所有东西(包装JPA实现等)添加包装王。

长篇故事... Spring preffer XML解决方案(XML脚本引擎... brrrr)的大部分部分,所以对于DI我使用Guice

良好的库,但随着越来越depnedenciec,例如Sprong JDBC(也许一个Java jdbc解决方案与实名参数)接下来从maven 4-5。

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