初识Spring Framework

最近在工作用到了Spring框架,由于以前没有接触过Spring,就从Spring的官方文档开始学起。在“Quick Start”介绍了一个使用Spring做依赖性注入(dependency injection)的例子,该例子使用Maven或GRADlE进行管理的。作者以前没有接触过这两个项目管理工具,由于时间紧迫,就直接使用了Eclipse编译了这个例子。在Eclipse下的文件结构如下:

(由于没有使用项目管理工具,刚开始只加入了spring-context.jar和spring-core.jar,又根据异常信息导入了commouns-logging.jar、spring-expression.jar和spring-beans.jar。这就是不是项目管理工具的麻烦所在。)

hello/MessageService.java的代码如下:

package hello;

public interface MessageService {
    String getMessage();
}

hello/MessagePrinter.java的代码如下:

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MessagePrinter {

    final private MessageService service;

    @Autowired
    public MessagePrinter(MessageService service) {
        this.service = service;
    }

    public void printMessage() {
        System.out.println(this.service.getMessage());
    }
}

hello/App.java的代码如下:

package hello;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan
public class App {

    @Bean
    MessageService mockMessageService() {
        return new MessageService() {
            public String getMessage() {
              return "Hello World!";
            }
        };
    }

  public static void main(String[] args) {
      ApplicationContext context =
          new AnnotationConfigApplicationContext(App.class);
      MessagePrinter printer = context.getBean(MessagePrinter.class);
      printer.printMessage();
  }
}

编译运行该项目,会有以下输出:

“Quick Start”最后总结说这个充分体现了依赖性注入(dependency injection)的概念,至于如何体现的作者尝试做一下解析,权当对Spring Framework的一个初步认识。

项目的入口是App.java的main函数,在这个函数中首先声明了一个ApplicationContext对象context,并向下转型为AnnotationConfigApplicationContext对象。ApplicationContext是对一个应用(Application)提供配置的核心接口,AnnotationConfigApplicationContext是它的一个实现,可用来处理用@Configuration,@Component和JSR-330标注的类。由于App.java使用@Configuration进行了标注,故App.class可以作为AnnotationConfigApplicationContext构造器的的参数。

 MessagePrinter printer = context.getBean(MessagePrinter.class);

这句代码通过context的getBean(Class<T>)方法得到了MessagePrinter的一个实例。为什么呢得到MessagePrinter类的一个实例呢?看getBean(Class<T>)的API解释:

Return the bean instance that uniquely matches the given object type, if any.

(如果给定的对象唯一匹配,就返回一个bean实例。)

 printer.printMessage();

调用MessagePrinter的printMessage()方法,该方法如下实现:

 public void printMessage() {
        System.out.println(this.service.getMessage());
    }

其实是调用了接口MessageService的getMessage()方法,由于App.java中的mockMessageService()方法中的匿名内部类实现了MessageService接口,并在getMessage()方法中返回了“hello,world!”字符串,顾能在结果中输出"hello,world!"。

令人迷惑的是在mockMessageService()方法并没有被显式调用,为何其匿名内部类能被实例化并输出信息呢?原因就在于程序中使用的以下Spring标注。

@Configuration 用于标注一个类,表示bean定义的源文件(source);

@Bean 用于标注一个方法,表示一个方法实例化、配置或初始化一个新的对象(Object),这个对象被Spring的控制反转(IoC)容器管理,相当于Spring <bean />XML配置文件中<bean />元素。(详见官方文档

@ComponentScan  用于标注一个类,表示扫描指定包中的@Component标注的类,并将这些类注册为Spring IoC容器的bean,亦相当于一个<bean />元素;

@Autowired  用于标注setter方法,构造器,包含多个参数的方法,集合等等,用于自动绑定;

@Component  用于标注一个类

由于MessagePrinter中有如下构造器:

  @Autowired
    public MessagePrinter(MessageService service) {
        this.service = service;
    }

从这个构造器中可以到MessagePrinter依赖MessgeServie,并用@Autowired标注。这就表示在通过contexnt.getBean(MessagePrinter.class)得到MessagePrinter的一个实例时,会将对MessageService的依赖自动绑定到MessageService类,将查找所有能作为<bean />元素的类(@Component @Configuration标注)或方法(@Bean标注),而在App.java中有如下方法:

 @Bean
    MessageService mockMessageService() {
        return new MessageService() {
            public String getMessage() {
              return "Hello World!";
            }
        };
    }

查找到这个方法后会将这个MessageService实现注入到MessagePrinter实例中,从而实现“hello,world!”的输出。

以上就是作者对Spring Framework文档“Quick Start”例子的解析,有不当之处=请多多指教。

时间: 03-06

初识Spring Framework的相关文章

Spring Framework 初识

Spring Framework Spring Framework 提供了一种综合的企业级应用的开发配置模型. 特性: 核心技术:依赖注入.事件.资源管理.国际化.数据校验.数据绑定.类型转换.AOP等 测试: 提供了测试框架 数据访问:事务管理.支持DAO.JDBC.ORM 提供了 Spring MVC 和Spring WebFlux 两种Web框架 集成:JMS.JCA.JMX.缓存等 语言:Groovy.Kotlin等 架构图: Spring Core:提供核心工具类 Spring Aop

手动创建Spring项目 Spring framework

之前学习框架一直是看的视频教程,并且在都配套有项目源码,跟着视频敲代码总是很简单,现在想深入了解,自己从官网下载文件手动搭建,就遇到了很多问题记载如下. 首先熟悉一下spring的官方网站:http://spring.io/ 平时所说的Spring就是Spring中的一个项目,主页为Project --> Spring Framework : http://projects.spring.io/spring-framework/ 介绍了spring framework的基础配置和使用maven搭

Spring Framework简介

Spring Framework 学习java编程不知不觉已经三年时间了,开始的时候,总是喜欢看着视频,然后按部就班的敲打着键盘,每当系统正常运行后,心里乐开了花.最开始的时候,所有的代码都是由自己设计,基本上不使用第三方java类.但是随着学习的深入,逐渐的开始接触各种第三方java类库,比如apache common,dom4j,log4j等.同样的,为了降低系统开发的复杂度,大部分系统也会采用业界经典的框架结构来构建,比如:struts + spring + orm(ssh),spring

关于spring framework最新发布压缩包的下载问题 【非常非常新手帖】

关于spring framework最新发布压缩包的下载问题 [非常非常新手帖] - Java之道 - 博客频道 - CSDN.NET 最近,spirng官方改版,spring framework最新release的zip包已经在官网上找不着相应链接了,都改成maven构建下载的方式了,让初学者无从下载. 这里给大家提供springframework最新release的zip包的下载地址: ?1. 在浏览器中打开这个地址 http://maven.springframework.org/rele

Spring Framework------&gt;version4.3.5.RELAESE-----&gt;Reference Documentation学习心得-----&gt;Spring Framework中的spring web MVC模块

spring framework中的spring web MVC模块 1.概述 spring web mvc是spring框架中的一个模块 spring web mvc实现了web的MVC架构模式,可以被用于开发web网站 spring web mvc 实现web网站的原理,如下图: 2.使用spring web mvc开发web应用的步骤 step1:在自己的工程中引入spring web mvc模块 step2:配置spring web mvc模块 中的DispatcherServlet,告

Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的人,但事实并非如此,例如我.好在闷着头看了一遍,又查资料又敲代码,总算明白了. 其实说穿了一文不值,我们用一个例子来解释: 假定,现有一个app,功能是接收你输入的生日,然后显示你的年龄.看起来app只要用当前日期减去你输入的日期就是年龄,应该很简单对吧?可惜事实不是这样的. 这里面有三个问题: 问题一:我们输入的永远是字符串,字符串需要转成日期格式才能被我们的ap

Spring Framework源码(六):Spring AOP之解析标签

首先看下spring framework配置例子: <aop:config> <aop:aspect id="myaop" ref="log"> <aop:pointcut id="mycut" expression="execution(* cn.itcast.service..*.*(..))"/> <aop:before pointcut-ref="mycut"

Spring Framework Ecosystem – Introduction to Spring Projects

来自于:http://springtutorials.com/spring-ecosystem/ Hello and Welcome to Spring Tutorials Blog! Is it fair to assume you have at least heard of Spring Framework official website – spring.io? If not, I would recommend that you check it out. There are som

[JavaEE - JPA] 3. Spring Framework中的事务管理

前文讨论了事务划分(Transaction Demarcation)在EJB中是如何实现的,本文继续介绍在Spring Framework中是如何完成事务划分的. 我们已经知道了当采用Container事务类型的时候,事务划分主要有以下两种方案(参考这里): 使用JTA接口在应用中编码完成显式划分 在容器的帮助下完成自动划分 在使用JavaEE的EJB规范时,这两种方案分别被实现为BMT以及CMT,关于BMT和CMT在上一篇文章中有比较详尽的讨论(参考这里). 那么对于Spring Framew