Spring架构模块
Spring架构设计图
Spring架构主要分为 核心容器模块,Web/Remoting模块,数据访问/集成模块,Test模块
核心容器:包括Core、Beans、Context、EL模块。
- Core模块:封装了框架依赖的最底层部分,包括资源访问、类型转换及一些常用工具类。
- Beans模块:提供了框架的基础部分,包括反转控制和依赖注入。其中Bean Factory是容器核心,本质是“工厂设计模式”的实现,
- Context模块:以Core和Beans为基础,集成Beans模块功能并添加资源绑定、数据验证、国际化、Java EE支持、容器生命周期、事件传播等;核心接口是ApplicationContext
- AOP模块:Spring AOP模块提供了符合 AOP Alliance规范的面向方面的编程(aspect-oriented programming)实现,提供比如日志记录、权限控制、性能统计等通用功能和业务逻辑分离的技术,并且能动态的把这些功能添加到需要的代码中;这样各专其职,降低业务逻辑和通用功能的耦合。
数据访问/集成模块:该模块包括了JDBC、ORM、OXM、JMS和事务管理
- 事务模块:该模块用于Spring管理事务,只要是Spring管理对象都能得到Spring管理事务的好处,无需在代码中进行事务控制了,而且支持编程和声明性的事物管理。
- JDBC模块:提供了一个JBDC的样例模板,使用这些模板能消除传统冗长的JDBC编码还有必须的事务控制,而且能享受到Spring管理事务的好处。
- JMS模块:用于JMS(Java Messaging Service),提供一套 “消息生产者、消息消费者”模板用于更加简单的使用JMS,JMS用于用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
Web/Remoting模块:Web/Remoting模块包含了Web、Web-Servlet、Web-Struts、Web-Porlet模块。
- Web模块:提供了基础的web功能。例如多文件上传、集成IoC容器、远程过程访问(RMI、Hessian、Burlap)以及Web Service支持,并提供一个RestTemplate类来提供方便的Restful services访问。
- Web-Servlet模块:提供了一个Spring MVC Web框架实现。Spring MVC框架提供了基于注解的请求资源注入、更简单的数据绑定、数据验证等及一套非常易用的JSP标签,完全无缝与Spring其他技术协作。
Test模块: Spring支持Junit和TestNG测试框架,而且还额外提供了一些基于Spring的测试功能,比如在测试Web框架时,模拟Http请求的功能
IOC
Ioc—Inversion of Control,即“控制反转”
控制:IoC是有专门一个容器来创建对象,即由Ioc容器来控制对象的创建。创建对象的过程的控制权由程序员转移给了IOC容器。
反转:手动创建对象时是主动控制直接去获取该对象创建所需要依赖的其他资源或者对象,而反转则是由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转。
把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
传统应用程序示意图
有IoC/DI容器后程序结构示意图
IoC容器的概念
IoC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖, 在Spring中BeanFactory是IoC容器的实际代表者。
Spring IoC容器通过读取配置文件中的配置元数据,通过元数据对应用中的各个对象进行实例化及装配。一般使用XML配置元数据。可用其他方式:如注解,属性文件之类配置都可。
Bean的概念
由IoC容器管理的那些组成你应用程序的对象我们就叫它Bean, Bean就是由Spring容器初始化、装配及管理的对象,在spring配置文件中来配置元数据,指定如何实例化,组装Bean。
在Spring Ioc容器的代表就是org.springframework.beans包中的BeanFactory接口
ApplicationContext接口扩展了BeanFactory,还提供了与Spring AOP集成、国际化处理、事件传播及提供不同层次的context实现
Bean的实现:
//ClassPathXmlApplicationContext:ApplicationContext实现,从classpath获取配置文件;
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath.xml");
//FileSystemXmlApplicationContext:ApplicationContext实现,从文件系统获取配置文件
BeanFactory beanFactory = new FileSystemXmlApplicationContext("fileSystemConfig.xml");
//XmlWebApplicationContext:从Web系统中的XML文件来载入Bean定义的信息。
ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext ctx =
WebApplicationContextUtils.getWebApplicationContext(servletContext);
ApplicationContext接口获取Bean
Object context.getBean(name);
IOC工作过程
一、准备配置文件:就像前边Hello World配置文件一样,在配置文件中声明Bean定义也就是为Bean配置元数据。
二、由IoC容器进行解析元数据: IoC容器的Bean Reader读取并解析配置文件,根据定义生成BeanDefinition配置元数据对象,IoC容器根据BeanDefinition进行实例化、配置及组装Bean。
三、实例化IoC容器:由客户端实例化容器,获取需要的Bean
Bean的命名
1、不指定id,只配置必须的全限定类名,由IoC容器为其生成一个标识,客户端必须通过接口
“T getBean(Class< T > requiredType)”获取Bean;
< bean class="cn.javass.spring.chapter2.helloworld.HelloImpl"/>
HelloApi helloApi = beanFactory.getBean(HelloApi.class);
2、指定id,必须在Ioc容器中唯一;
< bean id="bean" class="cn.javass.spring.chapter2.helloworld.HelloImpl" />
//根据id获取bean
HelloApi bean = beanFactory.getBean("bean", HelloApi.class);
3、指定name,这样name就是“标识符”,必须在Ioc容器中唯一;
<bean name="bean" class="cn.javass.spring.chapter2.helloworld.HelloImpl"/>
//根据name获取bean
HelloApi bean = beanFactory.getBean("bean", HelloApi.class);
在XML中id是一个真正的XML id属性,因此当其他的定义来引用这个id时就体现出id的好处了,可以利用XML解析器来验证引用的这个id是否存在,从而更早的发现是否引用了一个不 存在的bean,而使用name,则可能要在真正使用bean时才能发现引用一个不存在的bean。
Bean的实例化
Spring IoC容器则需要根据Bean定义里的配置元数据使用反射机制来创建Bean。
1、使用构造器实例化Bean
< bean name="bean2" class="cn.javass.spring.chapter2.HelloImpl2">
<!-- 指定构造器参数 -->
< constructor-arg index="0" value="Hello Spring!"/>
</ bean>
使用< constructor-arg >标签指定构造器参数值,其中index表示位置,value表示常量值,
2、使用静态工厂方式实例化Bean
除了指定必须的class属性,还要指定factory-method属性来指定实例化Bean的方法,而且使用静态工厂方法也允许指定方法参数
静态工厂:
public class HelloApiStaticFactory {
//工厂方法
public static HelloApi newInstance(String message) {
//返回需要的Bean实例
return new HelloImpl2(message);
}
}
<!-- 使用静态工厂方法 -->
< bean id="bean3" class="cn.javass.spring.chapter2.HelloApiStaticFactory"
factory-method="newInstance">
<constructor-arg index="0" value="Hello Spring!"/>
</bean>
HelloApi bean3 = beanFactory.getBean("bean3", HelloApi.class);
3、使用实例工厂方法实例化Bean
不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法,而且使用实例工厂方法允许指定方法参数,方式和使用构造器方式一样
public class HelloApiInstanceFactory {
public HelloApi newInstance(String message) {
return new HelloImpl2(message);
}
}
<!—1、定义实例工厂Bean -->
<bean id="beanInstanceFactory"
class="cn.javass.spring.chapter2.HelloApiInstanceFactory"/>
<!—2、使用实例工厂Bean创建Bean -->
<bean id="bean4"
factory-bean="beanInstanceFactory"
factory-method="newInstance">
<constructor-arg index="0" value="Hello Spring!"></constructor-arg>
</bean>
HelloApi bean4 = beanFactory.getBean("bean4", HelloApi.class);