本篇章介绍Spring框架的完整地全部技术。
本人偏爱Java Configuration(也是Spring推荐的方式),所以同样配置的情况下,将略去XML配置不表,请知悉。
官翻版本:Spring Framework Core 5.2.5.RELEASE
因为考虑到考研,项目开发等,所以文章更新会慢一些,如果你喜欢的话,也可以私信我提醒更新!
需要的基础知识:
Java SE(Version 11.0+) Maven(Version 3.62+) JetBrains IntelliJ IDEA(Version 2019.3.4+) GitHub 复制代码
配置元数据:配置源或配置文件的意思。
依赖:顾名思义,构建某个实例需要的其他实例,因为依赖于这个实例,所以叫“依赖”。
Bean:中文翻译“豆子,黄豆”,就是一个类实例,只是这个类只有getter/setter方法和私有域而已,常作为数据载体。
DAO: 数据库访问类(Data Access Object),就是一类专门用来访问数据库的Bean
在Spring Framework中,最重要的莫过于Spring Framework的Inversion Of Control(IOC)控制反转。本文会先介绍IOC技术,之后是完整且全面的Spring Framework Aspect-Oriented Programming(AOP)面向切面编程。从概念上说,Spring的AOP是很好理解的,同时它也可以解决企业编程的80%的AOP问题。
Spring整合了AspectJ(一个当前特性最丰富,最成熟的Java企业级AOP实现)。(暗示Spring的AOP很牛逼)
IOC也作为Dependency Injection(DI)依赖注入而被人知晓。它是一个定义对象依赖的过程,对象从构造参数,工厂方法参数,属性值获取创建此对象需要的依赖(其实就是其他对象)。
容器就有点秀了!它在对象需要依赖时(需要其他对象时)主动地注入进去,这个过程本质上通过直接构造类或者类似服务定位模式的机制来取代bean实现对于依赖的实例化或定位过程,“接管了”对象对于依赖的控制,就像“反转一样”,所以叫控制反转(Inversion of Control)。
org.springframework.beans和org.springframework.context这两个包是Spring Framework IOC容器的基础包,其中:BeanFactory接口提供了一种高级配置机制,这种机制可以管理任何类型的对象。ApplicationContext是它的一个子接口,它拥有:
a)更简单地整合Spring AOP特性。 b)管理资源处理。 c)发布事件。 d)应用层次的特殊上下文(context),比如在Web应用中的WebApplicationContext。 复制代码
简而言之,BeanFactory提供了配置框架和基础功能,ApplicationContext添加一些企业开发方面的功能。Application是BeanFactory的一个完全的超集,本章仅仅用它来描述Spring IOC容器,想要了解更多关于BeanFactory, 详见这里
在Spring里,构成你应用骨干的对象实例被称为“bean”,bean是啥呢?是一个实例化了的,组装了的,同时被Spring IOC容器管理的对象。bean仅仅是你应用中的众多对象之一。所有的Bean以及他们所使用的依赖,都被容器使用配置元数据利用反射管理着。
org.springframework.ApplicationContext接口代表了Spring IOC容器,它负责实例化,配置和装配bean。容器通过读取配置元数据来决定对哪个对象进行实例化,配置,和装配。元数据以XML, Java注解或Java代码形式。它让你可以清楚地指明构成你应用的对象,以及它们之间丰富的内部依赖关系。
下图展示了Spring是怎么工作的:
正如图所示的那样,Spring IOC容器使用一个配置元数据构成的表单。这个含有配置元数据的表单,代表着你,也就是此应用的开发者,希望Spring容器应该怎样实例化,配置和装配你应用中的Bean组件。
传统的设置配置元数据的方法是使用简单直观明了的XML形式,这也是本章主要的配置方法。
P.s. XML并不是唯一的格式,Spring IOC容器已经从之解耦出来了,当下,越来越多的开发者使用基于Java注解的配置方法(比如我)。 复制代码
想要了解更对其他配置格式?
* 基于注解的配置 (Spring 2.5引入)
* 基于Java的配置 (Spring 3.0引入,一些由Spring JavaConfig提供的特性逐渐成了Spring Framework的核心,所以你可以使用Java配置为你的应用提供外部Bean而不是使用XML文件,想使用这些新特性?试试 @Configuration , @Bean , @Import , @DependsOn )
Spring配置考虑到容器至少管理一个(通常很多个)Bean定义,Java配置在@Configuration注解修饰的类里面使用@Bean注解来完成定义这些Bean。
这些Bean定义与实例对象联系起来然后修饰你的应用。通常情况下,你会定义业务层对象,比如数据库访问对象(DAO. Data Access Object),表示对象,例如Struts Action实例,基础结构对象,例如Hibernate SessionFactories,JMS队列,诸如此类。一般来说,加载域对象是DAO或业务逻辑的职责,所以容器里面不会有细粒化的域对象。不过,你可以使用Spring对于AspectJ的整合来配置IOC容器控制之外创建的对象。 详见 。
简单用法:
public class Book { // ... } @Configuration public class WebConfig { // ... @Bean(name = "book") public Book book() { return new Book(); } } 复制代码
若需要在某个配置类引用其他的配置类,可以在类前面加上:
@Import(value = {ConfigA.class, ConfigB.class}) 复制代码
通过使用:
T getBean(String name, Class<T> requiredType) 复制代码
方法,可以获取Bean实例。
但是,理想情况下,你不应该使用getBean()方法,因为这会破坏容器对于对象的自动管理,你可以使用诸如@Autowired的注解来在特殊Bean里面获取你需要的依赖。(说白了,别有事没事调用getBean(),测试除外,那不然,你还有IOC容器帮你管理干啥?直接自己整呗!弟弟!)
在IOC容器里面,Bean的定义以BeanDefinition的形式呈现。它们包含以下的元数据:
a)包限定名的类,包含了Bean的实现类。 b)Bean行为定义组件,定义了Bean在IOC容器里面的行为。 c)对于此Bean需要的其他Bean的引用,这些引用又被称为“合作者”或“依赖”。 d)其他用于设置新创建的Bean的配置,比如超时时间,数据库连接池数量等。 复制代码
元数据被传递到一个配置集合中,以用来表达Bean定义。
具体的Bean配置集合, 详见 。
ApplicationContext还允许用户在容器外面自定义Bean。通过ApplicationContext的getBeanFactory()方法获取,此方法返回BeanFactory的DefaultListableBeanFactory实现,DefaultListableBeanFactory支持通过registerSingleton(..)和registerBeanDefinition(..)来注册Bean。不过,通常情况下,应用只能和通过配置元数据定义的Bean协作。