Java学习之Spring
1、Spring是以简化Java EE应用程序开发而创建的。Spring整体框架大概分为20个模块,如下图:
Core和Beans是框架的基础部分,提供IoC和依赖注入特性。
Core主要包含Spring框架基本的核心工具类,Spring其它组件都要用到这个包里的类。
Beans模块是所有应用都要用到的。它包含访问配置文件、创建和管理bean以及进行Inversion of Control/Dependency Injection(IoC/DC)操作相关的所有类。
Context模块构建与Core和Beans模块之上,提供了一种类似于JNDI注册器的框架式的对象访问方法,ApplicationContext接口是Context模块的关键。
Expreesion Language提供了一个强大的表达式语言用于在运行时查询和操纵对象。
JDBC模块提供了一个JDBC抽象层,包含了Spring对JDBC数据访问进行封装的所有类。
ORM模块为流行的对象-关系映射API,如JPA、JDO、Hibernate、MyBatis等。
OXM模块提供了一个对Object/XML映射实现的抽象层。
JMS主要包含了制造和消费消息的特性。
Transaction支持编程和声明性的事务管理。
Web模块提供了基础的面向Web的集成特性。Web-Servlet模块包含Spring的MVC实现。Web-Struts模块提供了对Struts的支持。Web-Porlet模块提供了用于Porlet环境和Web-Servlet的MVC实现。
AOP模块提供了一个符合AOP联盟标准的面向切面编程的实现,可以很容易地使Spring管理的 任何对象支持AOP。
Aspects模块提供了对AspectJ的集成支持。
Instrumentation模块提供了对class instrumentation支持和classloader实现。
Test模块支持使用JUnit和TestNG对Spring组件进行测试。
类比操作系统,AOP和IoC是Spring的Kernel,代表可最基础的底层抽象,也是Spring其它模块实现的基础。
Spring使用POJO开发,各个模块除了依赖AOP和IoC之外,相互之间没有很强的耦合性。相对于EJB,Spring降低应用的负载和框架的侵入性。
2、Spring IoC容器
任何一个有意义的应用都会由两个或更多的类组成,这些类之间相互协作来完成特定的业务逻辑,按照传统的做法每个对象负责管理与自己相互协作的对象的引用,这会导致高度耦合而难以测试。
如果一个对象只通过接口来表明依赖关系,那么这种依赖就能在对象本身毫不知情的情况下,用不同的具体实现替换。
Spring IoC容器设计中,有两个主要的容器系列:实现BeanFactory接口的简单容器系列,ApplicationContext应用上下文。
我们通常所说的IoC容器代表一系列功能各异的容器产品,Spring有各式各样的IoC容器的实现供用户选择和使用。BeanFactory体现了Spring为提供给用户使用的容器所设定的最基本的功能规范。在此基础上,Spring定义BeanDefinition来管理基于Spring应用中的各种对象以及它们之间的相互依赖关系。
IoC容器设计接口图
BeanFactory——>HierarchicalBeanFactory——>ConfigurableBeanFactory是一条主要的BeanFactory设计路径;
以ApplicationContext为核心的接口设计是第二条设计主线。
一般在开发应用时以ApplicationContext作为基本的IoC容器的基本形式。
IoC容器的初始化过程:BeanDefinition的Resource定位——>BeanDefinition的载入和解析——>BeanDefinition在IoC容器中的注册
依赖注入的过程是用户第一次向IoC容器索要bean时触发的,
bean在Spring容器中的生命周期
3、bean的装配
创建应用组件之间协作的行为通常称为装配,这也是依赖注入的本质。Spring负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,你需要告诉Spring需要创建哪些bean并且如何装配在一起,Spring有多种装配bean的方式:在XML中进行显式配置、在Java中进行显式配置、隐式的bean发现机制和自动装配。尽可能使用自动配置,显式配置越少越好,必须显式配置时优先Java配置,最后才是XML配置。
自动化装配依赖组件扫描和自动装配,@Component、@Component;为组件扫描的bean命名,@Component("xxx")或@Named("xxx");可以设置组件扫描的基础包;@Autowired和@Inject实现自动装配。
自动化装配有时候不行,比如你要将第三方库装配到你的应用中,因为你不是代码维护人,所以你不能通过注解实现自动化装配。创建JavaConfig配置类的关键在于添加@Configuration注解,@Bean注解方法。
基于XML文件装配bean,<beans> <bean id="xxx" class="yyy"/> </beans>,通过构造器注入bean。
bean profile,@Profile注解基于**的profile实现bean的装配。Spring在确定哪个profile处于**状态时依赖spring.profiles.active和spring.profiles.default属性。
条件化的bean,@Conditional
处理自动自动装配的歧义性:@Primary标识首选bean;@Qualifier限定装配哪个bean。
4、bean的作用域
默认情况下,Spring应用上下文中所有bean都是以单例的形式创建的,有时候不能用单例,因此Spring定义了多种作用域,基于这些作用域创建bean,包括:单例、原型、会话和请求。@Scope
5、运行时值注入
Spring提供了两种在运行时求值的方式:属性占位符和Spring表达式SpEL。属性占位符${...}。
SpEL拥有很多特性,包括:使用bean的ID来引用bean,调用方法和访问对象的属性,对值进行算术、关系和逻辑运算,正则表达式匹配,集合操作。SpEL要放到#{...}之中,
6、AOP(aspect-oriented programming)
DI可以让相互协作的软件组织保持松耦合,而AOP允许你把遍布应用各处的功能分离出来形成可重用的组件。切面是覆盖在很多组件之上的一个外壳。
散布于应用中多处的功能被称为横切关注点,通常来讲,这些横切关注点是与应用的业务逻辑相分离的,把这些横切关注点与应用的业务逻辑相分离正是AOP要解决的问题。横切关注点可以被模块化为特殊的类,这些类被称为切面。
切面的工作被称为通知。Spring切面可以应用5种类型的通知:前置通知、后置通知、返回通知、异常通知、环绕通知。
时机被称为连接点,连接点是应用程序在执行过程中能够插入切面的一个点。切面代码可以这些点插入到应用的正常流程之中,并添加新的行为。
切点缩小切面通知的连接点的范围。
切面是通知和切点的结合。
引入:允许向现有的类添加新方法或属性。
织入:把切面应用到目标对象并创建新的代理对象的过程。在目标对象的生命周期里,有多个点可以进行织入:编译期、类加载期、运行期。Spring AOP是在运行期织入的。
Spring提供4种AOP支持:基于代理的经典Spring AOP、纯POJO切面、@AspectJ注解驱动切面、注入式AspectJ切面。
在Spring AOP实现中,使用的核心技术是动态代理,通过JDK的代理特性,可以为任意对象创建代理对象,对于具体使用来说,这个特性是通过Java Reflection API来完成的。Spring只支持方法连接点,而AspectJ和JBoss还支持字段和构造器接入点。如果需要在方法拦截之外的连接点拦截功能,可以利用AspectJ来补充Spring AOP的功能。
7、在Spring AOP中,要使用AspectJ的切点表达式语言来定义切点,Spring只支持AspectJ切点指示器的一个子集,
只有execution指示器是实际执行匹配的,其它的都是用来限制匹配的,
编写切点
Spring使用AspectJ注解来声明通知的方法:
在XML中声明切面:
8、