0.框架
框架,即framework。框架一般是成熟的,不断升级的软件。是对特定应用领域中的应用系统的部分设计和实现的整体结构。
因为软件系统发展到今天已经很复杂了,特别是服务器端软件,涉及到的知识,内容,问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。而且框架一般是成熟,稳健的,他可以处理系统很多细节问题,比如,事务处理,安全性,数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。
1、Spring简介
- Spring是一个开源框架
- Spring为简化企业级开发而生,使用Spring,JavaBean就可以实现很多以前要靠EJB才能实现的功能。
- Spring是一个IOC(DI)和AOP容器框架。
- Spring的优良特性
- 非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
- 依赖注入:DI——Dependency Injection,反转控制(IOC)最经典的实现。
- 面向切面编程:Aspect Oriented Programming——AOP
- 容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
- 组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
- 一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。
- Spring模块
1.1、搭建Spring运行时环境
- 加入JAR包
-
① Spring自身JAR包:spring-framework-4.0.0.RELEASE\libs目录下
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELE2ASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
② commons-logging-1.1.1.jar
-
- 在Spring Tool Suite工具中通过如下步骤创建Spring的配置文件
① File->New->Spring Bean Configuration File
② 为文件取名字 例如:applicationContext.xml
1.2、HelloWord
- 创建一个实体类
package cn.edu.hbuas.entity; public class Person { private Integer id; private String name; public Person() { } public Person(Integer id, String name) { super(); this.id = id; this.name = name; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + "]"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
- 创建Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="person" class="cn.edu.hbuas.entity.Person" > <property name="id" value="111"></property> <property name="name" value="小明"></property> </bean> </beans>
- 测试:通过Spring的IOC容器创建Student类实例
package cn.edu.hbuas.main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.edu.hbuas.entity.Person;
public class TestBySpring {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ac =new ClassPathXmlApplicationContext("applicationContext.xml");
Person person=(Person)ac.getBean("person");
System.out.println(person);
}
}
2、IOC容器和Bean的配置
2.1、IOC(Inversion of Control):反转控制
反转控制的思想完全颠覆了应用程序组件获取资源的传统方式:反转了资源的获取方向——改由容器主动的将资源推送给需要的组件,开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源的方式即可,极大的降低了学习成本,提高了开发的效率。这种行为也称为查找的被动形式。
传统方式: 我想吃饭 我需要买菜做饭
反转控制: 我想吃饭 张口就行
2.2、DI(Dependency Injection):依赖注入
IOC的另一种表述方式:即组件以一些预先定义好的方式(例如:setter 方法)接受来自于容器的资源注入。相对于IOC而言,这种表述更直接。
总结: IOC 就是一种反转控制的思想, 而DI是对IOC的一种具体实现。
2.3、IOC容器在Spring中的实现
IOC容器在最底层实质上就是一个对象工厂.
1)在通过IOC容器读取Bean的实例之前,需要先将IOC容器本身实例化。
2)Spring提供了IOC容器的两种实现方式
① BeanFactory:IOC容器的基本实现,是Spring内部的基础设施,是面向Spring本身的,不是提供给开发人员使用的。
② ApplicationContext:BeanFactory的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有场合都使用ApplicationContext而不是底层的BeanFactory。
ApplicationContext的主要实现类:
- ClassPathXmlApplicationContext:对应类路径下的XML格式的配置文件
- FileSystemXmlApplicationContext:对应文件系统中的XML格式的配置文件
- 在初始化时就创建单例的bean,也可以通过配置的方式指定创建的Bean是多实例的。
2.4、给bean的属性赋值
2.4.1、依赖注入的方式
1. 通过bean的setXxx()方法赋值
Hello World中使用的就是这种方式
2. 通过bean的构造器赋值
- Spring自动匹配合适的构造器
- 通过索引值指定参数位置
3.P名称空间
为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息。Spring从2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean 的属性。使用p命名空间后,基于XML的配置方式将进一步简化。
2.4.2、为属性赋值时可用的值
-
字面量
- 可以使用字符串表示的值,可以通过value属性或value子节点的方式指定
- 基本数据类型及其封装类、String等类型都可以采取字面值注入的方式
- 若字面值中包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起来
- null值
<bean class="cn.edu.hbuas.entity" id="bookNull" > <property name= "id" value ="2000"/> <property name= "name"> <null/> </property> </bean >
3.引用类型
<bean id="action" class="cn.edu.hbuas.action">
<property name="service" ref="service"/>
<property name="service.dao.dataSource" value="DBCP"/>
</bean>
4.集合属性
数组和List
- 配置java.util.List类型的属性,需要指定<list>标签,在标签里包含一些元素。
- 可以通过<value>指定简单的常量值,通过<ref>指定对其他Bean的引用。
- 配置java.util.Set需要使用<set>标签,定义的方法与List一样。
<bean id="shop" class="cn.edu.hbuas.bean.Shop" >
<property name= "categoryList">
<!-- 以字面量为值的List集合 -->
<list>
<value> 历史</value >
<value> 军事</value >
</list>
</property>
<property name= "bookList">
<!-- 以bean的引用为值的List集合 -->
<list>
<ref bean= "book01"/>
<ref bean= "book02"/>
</list>
</property>
</bean >
Map
- Java.util.Map通过<map>标签定义,<map>标签里可以使用多个<entry>作为子标签。一个entry相当于一条键值对。
- 必须在<key>标签里定义键。
- 因为键和值的类型没有限制,所以可以自由地为它们指定<value>、<ref>、<bean>或<null/>
<bean id="cup" class="cn.edu.hbuas.bean.Cup">
<property name="bookMap">
<map>
<entry>
<key>
<value>1001</value>
</key>
<value>孙老师</value>
</entry>
<entry>
<key>
<value>bookKey02</value>
</key>
<ref bean="book02"/>
</entry>
</map>
</property>
</bean>
2.5、FactoryBean
Spring中有两种类型的bean,一种是普通bean,另一种是工厂bean,即FactoryBean。
- 工厂bean跟普通bean不同,其返回的对象不是指定类的一个实例,而是该工厂bean的getObject方法所返回的对象。
- 工厂bean必须实现org.springframework.beans.factory.FactoryBean接口。
<bean id="product" class="cn.edu.hbuas.bean.ProductFactory">
<property name="productName" value="Mp3" />
</bean>
2.6、bean的作用域
- 在Spring中,可以在<bean>元素的scope属性里设置bean的作用域,以决定这个bean是单实例的还是多实例的。
- 默认情况下,Spring只为每个在IOC容器里声明的bean创建唯一一个实例,整个IOC容器范围内都能共享该实例:所有后续的getBean()调用和bean引用都将返回这个唯一的bean实例。该作用域被称为singleton,它是所有bean的默认作用域。
当bean的作用域为单例时,Spring会在IOC容器对象创建时就创建bean的对象实例。而当bean的作用域为prototype时,IOC容器在获取bean的实例时创建bean的实例对象。
2.7、bean的生命周期
Spring IOC容器对bean的生命周期进行管理的过程:
① 通过构造器或工厂方法创建bean实例
② 为bean的属性设置值和对其他bean的引用
③ 调用bean的初始化方法
④ bean可以使用了
⑤ 当容器关闭时,调用bean的销毁方法
在配置bean时,通过init-method和destroy-method 属性为bean指定初始化和销毁方法
bean的后置处理器
① bean后置处理器允许在调用初始化方法前后对bean进行额外的处理
② bean后置处理器对IOC容器里的所有bean实例逐一处理,而非单一实例。
其典型应用是:检查bean属性的正确性或根据特定的标准更改bean的属性。
③ bean后置处理器需要实现接口:
org.springframework.beans.factory.config.BeanPostProcessor。在初始化方法被调用前后,Spring将把每个bean实例分别传递给上述接口的以下两个方法:
- postProcessBeforeInitialization(Object, String)
- postProcessAfterInitialization(Object, String)
- 添加bean后置处理器后bean的生命周期
①通过构造器或工厂方法创建bean实例
②为bean的属性设置值和对其他bean的引用
③将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法
④调用bean的初始化方法
⑤将bean实例传递给bean后置处理器的postProcessAfterInitialization()方法
⑥bean可以使用了
⑦当容器关闭时调用bean的销毁方法
2.8、自动装配
- 手动装配:以value或ref的方式明确指定属性值都是手动装配。
- 自动装配:根据指定的装配规则,不需要明确指定,Spring自动将匹配的属性值注入bean中。
2.8.1、装配模式
- 根据类型自动装配:将类型匹配的bean作为属性注入到另一个bean中。若IOC容器中有多个与目标bean类型一致的bean,Spring将无法判定哪个bean最合适该属性,所以不能执行自动装配
- 根据名称自动装配:必须将目标bean的名称和属性名设置的完全相同
2.9、通过注解配置bean
相对于使用注解的方式实现的自动装配,在XML文档中进行的自动装配略显笨拙,在项目中更多的使用注解的方式实现。
1.普通组件:@Component
标识一个受Spring IOC容器管理的组件
2.持久化层组件:@Repository
标识一个受Spring IOC容器管理的持久化层组件
3.业务逻辑层组件:@Service
标识一个受Spring IOC容器管理的业务逻辑层组件
4.表述层控制器组件:@Controller
标识一个受Spring IOC容器管理的表述层控制器组件
组件命名规则
- 默认情况:使用组件的简单类名首字母小写后得到的字符串作为bean的id
- 使用组件注解的value属性指定bean的id
注意:事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,@Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。
组件扫描
组件被上述注解标识后还需要通过Spring进行扫描才能够侦测到。
指定被扫描的package:
<context:component-scan base-package="类路径"/>
组件装配
Controller组件中往往需要用到Service组件的实例,Service组件中往往需要用到 Repository组件的实例。Spring可以通过注解的方式帮我们实现属性的装配。
@Autowired
- 根据类型实现自动装配。
- 构造器、普通字段、一切具有参数的方法都可以应用@Autowired 注解
- 默认情况下,所有使用@Autowired注解的属性都需要被设置。当Spring找不到匹 配的bean装配属性时,会抛出异常。
- 若某一属性允许不被设置,可以设置@Autowired注解的required属性为 false
- 默认情况下,当IOC容器里存在多个类型兼容的bean时,Spring会尝试匹配bean的id值是否与变量名相同,如果相同则进行装配。如果bean的id值不相同,通过类型的自动装配将无法工作。此时可以在@Qualifier注解里提供bean的名称。Spring甚至允许在方法的形参上标注@Qualifiter注解以指定注入bean的名称。
- @Autowired注解也可以应用在数组类型的属性上,此时Spring将会把所有匹配的bean进行自动装配。
- @Autowired注解也可以应用在集合属性上,此时Spring读取该集合的类型信息,然后自动装配所有与之兼容的bean。
- @Autowired注解用在java.util.Map上时,若该Map的键值为String,那么 Spring将自动装配与值类型兼容的bean作为值,并以bean的id值作为键。
@Resource
@Resource注解要求提供一个bean名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为bean的名称。
@Inject
@Inject和@Autowired注解一样也是按类型注入匹配的bean,但没有reqired属性。
来源:oschina
链接:https://my.oschina.net/u/4152684/blog/3162457