我听到很多关于Spring的消息,人们在网上都说Spring是一个很好的Web开发框架。 Spring Framework究竟是什么?
答案 0 :(得分:675)
基本上Spring是dependency-injection的框架,它是一种允许构建非常分离的系统的模式。
例如,假设您需要列出系统的用户,从而声明一个名为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文件或注释来连接类,这样所有对象都被Spring实例化并初始化,注入在右边地方(Servlets,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除了简单,优雅和稳定之外如此着名是SpringSource的人已经编写了许多POJO,它们有助于将Spring与其他许多常见的东西集成在一起框架在您的应用程序中没有侵入性。 Spring还有几个很好的子项目,比如Spring MVC,Spring WebFlow,Spring Security,还有一些loooong的etceteras列表。
希望这会有所帮助。无论如何,我鼓励你阅读关于依赖注入和控制反转的Martin Fowler's article,因为他做得比我好。 了解基础知识后,请查看Spring Documentation ,在我看来, 曾经是有史以来最好的Spring书。< / p>
答案 1 :(得分:59)
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,或者有时你可能想要Sedan。这取决于你想要的具体情况。
要解决此问题,您需要将工厂模式作为创建模式。工厂返回正确实例的地方。所以最终你会得到很多胶水代码,只是为了正确地实例化对象。没有胶水代码,Spring可以最好地完成胶水代码的工作。您在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
答案 2 :(得分:38)
过去, Spring 只是依赖注入框架工作( Guice , PicoContainer ,...),但现在是一天它是构建企业应用程序的完整解决方案。
弹簧依赖注入,当然是春天的核心仍然存在(你可以在这里查看其他好的答案),但春天还有更多......
Spring现在有很多项目,每个项目都有一些子项目(http://spring.io/projects)。当有人谈到春天时,你必须找出他正在谈论的春天项目,它是唯一的春天核心,它被称为 spring framework ,或者它是另一个春季项目。
值得一提的一些春季项目是:
如果您的应用程序需要更多指定功能,您也可以在那里找到它:
还有一些小项目,例如 spring-social-facebook (http://projects.spring.io/spring-social-facebook/)
您可以使用spring进行Web开发,因为它具有Spring MVC
模块,该模块是 Spring Framework 项目的一部分。或者你可以使用spring和另一个web框架工作,比如 struts2 。
答案 3 :(得分:23)
什么是春天?我将很快回答这个问题,但首先,让我们再看一下维克多·胡戈的例子。它不是一个很好的例子,因为它没有证明需要一个新的框架。
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和脚本!
那么春天是什么?它适用于:
答案 4 :(得分:18)
非常简短的总结,我会说Spring是你应用程序中的“胶水”。它用于集成不同的框架和您自己的代码。
答案 5 :(得分:13)
春天是三件事。
问题是Spring DI经过深思熟虑,围绕其他事情的包装器经过深思熟虑,因为其他东西都考虑到了所有东西,而Spring恰好包装好了。 MVC和REST的Spring实现以及所有其他的东西都做得不好(YMMV,恕我直言),但也有例外(Spring Security是炸弹)。 所以我倾向于使用Spring for DI,它的酷包装但更喜欢Web的其他东西(我喜欢Tapestry),REST(Jersey非常强大)等等。
答案 6 :(得分:11)
使用Spring在Web应用程序中可能需要的内容 -
此外,Spring是巨大的 - 所以你可能有兴趣在Spring AOP或Spring Security等Web应用程序中使用很多其他东西。但是上面列出的四件事描述了在Web应用程序中使用的Spring的常见组件。
答案 7 :(得分:8)
我看到两个部分:
请注意,您可以在不使用Spring MVC的情况下在Web应用程序中很好地使用Spring。我想说大多数Java Web应用程序都会这样做,同时使用其他Web框架,如Wicket,Struts,Seam,......
答案 8 :(得分:7)
Spring非常适合将类的实例粘合在一起。您知道您的Hibernate类总是需要一个数据源,Spring将它们连接在一起(并且还具有数据源的实现)。
您的数据访问对象将始终需要Hibernate访问,Spring将Hibernate类连接到您的DAO中。
此外,Spring基本上为您提供了一系列库的可靠配置,并在其中为您提供了应该使用哪些库的指导。
Spring真的是一个很棒的工具。 (我不是在谈论Spring MVC,只是基础框架)。
答案 9 :(得分:5)
由于Spring引入了对配置的各种注释的支持,因此接受的答案不涉及注释的使用。
还有另一种方法可以使用XML文件连接类:注释。让我们使用接受的答案中的示例,并使用其中一个注释@Component
,@Service
,@Repository
或@Configuration
直接在bean上注册:
@Component
public class UserListerDB implements UserLister {
public List<User> getUsers() {
// DB access code here
}
}
这种方式在创建视图时,它会神奇地准备好UserLister。
上述声明是有效的,不需要任何XML文件使用,并与另一个注释@Autowired
连接,找到相关的实现并将其注入。
@Autowired
private UserLister userLister;
在用于获取bean实现的方法上使用@Bean
注释。
答案 10 :(得分:4)
优点是Dependency Injection (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关键字创建对象,而是将对Lunch Type对象的引用作为构造函数的参数传递。在这里,对象创建是外包的。此代码可以使用Xml配置文件(旧版)或Java Annotations(现代版)进行连线。无论哪种方式,在运行时期间将决定创建哪种类型的对象。一个对象将由Xml注入到我们的代码中 - 我们的代码依赖于Xml来完成该工作。因此,依赖注入(DI)。 DI不仅有助于使我们的系统松散耦合,还简化了单元测试的编写,因为它允许依赖性被模拟。最后但并非最不重要的是,DI简化了面向方面编程(AOP),这导致了模块化的进一步解耦和增加。 另请注意,上面的DI是构造函数注入。 DI也可以通过Setter Injection完成 - 与封装相同的普通旧setter方法。
答案 11 :(得分:3)
Spring是Enterprise JavaBeans (EJB)技术的一个很好的替代品。它还有Web框架和Web服务框架组件。
答案 12 :(得分:2)
答案 13 :(得分:1)
Spring在开始时是依赖注入,然后为几乎所有东西添加包装王(JPA实现的封装器等)。
长篇故事...... Spring的大部分内容都是XML解决方案(XML脚本引擎...... brrrr),所以对于DI我使用Guice
好的库,但随着depnedenciec的增长,例如 Spring JDBC(可能是一个带有实名参数的Java jdbc解决方案)接下来是maven 4-5。
使用Spring MVC(“大春天”的一部分)进行Web开发......它是“基于请求”的框架,有圣战“请求与组件”......由你决定
答案 14 :(得分:1)
Spring作为一个相当简单的依赖注入系统开始。现在它很大,里面装着一切(除了众所周知的厨房水槽)。
但不要害怕,它非常模块化,所以你可以只使用你想要的部分。
要了解它的全部内容,请尝试:
它可能很旧,但它是一本很好的书。
这次专门讨论Spring的另一本好书:
它也引用了旧版本的Spring,但绝对值得一看。
答案 15 :(得分:0)
Spring框架对于针对Rest api更具体的Web开发非常有用。
这是因为它dependency injection并与其他模块集成,例如spring security,spring aop,mvc framework,microservices
您构建的任何应用程序肯定都需要安全性。
如果你正在构建一个产品,长期维护,那么你肯定会需要Aop概念
如果您的应用程序有更多的负载,那么您需要实现微服务。
Spring在一个平台上提供所有这些东西。支持many modules
主要的是spring是open source和可扩展的框架,到处都有一个钩子来集成生命周期中的自定义代码。
Spring Data是一个提供与项目集成的项目。
所以构建应用程序所需的一切都有Spring。
答案 16 :(得分:0)
过去我从纯粹的技术角度思考Spring框架。
鉴于团队工作和开发企业Web应用程序的一些经验 - 我会说Spring通过解耦其各个元素(bean)来“强大地”开发应用程序(Web应用程序) )。更快的发展使它如此受欢迎。 Spring允许将应用程序构建(连接)的责任转移到Spring框架上。 Spring框架的依赖注入负责将各个bean连接/连接到工作应用程序中。
这样,只要定义了bean之间的接口,开发人员就可以更专注于单个组件(bean)的开发。
这种应用程序的测试很容易 - 主要关注的是单个bean。它们可以很容易地解耦和模拟,因此单元测试快速而有效。
Spring框架定义了多个专用bean,例如 @Controller ( @Restcontroller ), @Repository , @Component 服务于网络目的。 Spring与Maven一起提供了一个对开发人员来说很直观的结构。 团队合作既简单又快捷,因为个别元素是分开的,可以重复使用。