回顾Spring(一)

我只是一个虾纸丫 提交于 2020-02-25 15:34:57

0.框架

框架,即framework。框架一般是成熟的,不断升级的软件。是对特定应用领域中的应用系统的部分设计和实现的整体结构。

因为软件系统发展到今天已经很复杂了,特别是服务器端软件,涉及到的知识,内容,问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。而且框架一般是成熟,稳健的,他可以处理系统很多细节问题,比如,事务处理,安全性,数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。

1、Spring简介

  1. Spring是一个开源框架
  2. Spring为简化企业级开发而生,使用SpringJavaBean就可以实现很多以前要靠EJB才能实现的功能。
  3. Spring是一个IOC(DI)AOP容器框架。
  4. Spring的优良特性
    • 非侵入式:基于Spring开发的应用中的对象可以不依赖于SpringAPI
    • 依赖注入DI——Dependency Injection,反转控制(IOC)最经典的实现。
    • 面向切面编程Aspect Oriented Programming——AOP
    • 容器Spring是一个容器,因为它包含并且管理应用对象的生命周期
    • 组件化Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XMLJava注解组合这些对象。
    • 一站式:在IOCAOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。
  5. Spring模块

1.1、搭建Spring运行时环境

  1. 加入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
  2. Spring Tool Suite工具中通过如下步骤创建Spring的配置文件

         ① File->New->Spring Bean Configuration File

         ② 为文件取名字 例如:applicationContext.xml

1.2、HelloWord

  1. 创建一个实体类
    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;
    	}
    	
    	
    }
    
  2. 创建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>
    

     

  3. 测试:通过SpringIOC容器创建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容器本身实例化。

2Spring提供了IOC容器的两种实现方式

               ① BeanFactory:IOC容器的基本实现,是Spring内部的基础设施,是面向Spring本身的,不是提供给开发人员使用的。

                ② ApplicationContext:BeanFactory的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有场合都使用ApplicationContext而不是底层的BeanFactory

ApplicationContext的主要实现类:

  1. ClassPathXmlApplicationContext:对应类路径下的XML格式的配置文件
  2. FileSystemXmlApplicationContext:对应文件系统中的XML格式的配置文件
  3. 在初始化时就创建单例的bean,也可以通过配置的方式指定创建的Bean是多实例的。

2.4、给bean的属性赋值

2.4.1、依赖注入的方式

    1. 通过beansetXxx()方法赋值

Hello World中使用的就是这种方式

    2. 通过bean的构造器赋值

 

  1. Spring自动匹配合适的构造器
  2. 通过索引值指定参数位置

    3.P名称空间

 

为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息。Spring2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean 的属性。使用p命名空间后,基于XML的配置方式将进一步简化。

2.4.2、为属性赋值时可用的值

  1.  字面量

    1. 可以使用字符串表示的值,可以通过value属性或value子节点的方式指定
    2. 基本数据类型及其封装类、String等类型都可以采取字面值注入的方式
    3. 若字面值中包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起来
  2. 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不同,其返回的对象不是指定类的一个实例,而是该工厂beangetObject方法所返回的对象。
  • 工厂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-methoddestroy-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)
  1. 添加bean后置处理器后bean的生命周期

         ①通过构造器或工厂方法创建bean实例

         ②bean属性设置值和对其他bean的引用

         ③bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法

         ④调用bean初始化方法

         ⑤bean实例传递给bean后置处理器的postProcessAfterInitialization()方法

         ⑥bean可以使用了

         ⑦当容器关闭时调用bean销毁方法

2.8、自动装配

  1. 手动装配:以valueref的方式明确指定属性值都是手动装配。
  2. 自动装配:根据指定的装配规则,不需要明确指定Spring自动将匹配的属性值注入bean中。

2.8.1、装配模式

  • 根据类型自动装配:将类型匹配的bean作为属性注入到另一个bean中。若IOC容器中有多个与目标bean类型一致的beanSpring将无法判定哪个bean最合适该属性,所以不能执行自动装配
  • 根据名称自动装配:必须将目标bean的名称和属性名设置的完全相同

 

2.9、通过注解配置bean

相对于使用注解的方式实现的自动装配,在XML文档中进行的自动装配略显笨拙,在项目中更多的使用注解的方式实现。

 

1.普通组件:@Component

                   标识一个受Spring IOC容器管理的组件

2.持久化层组件:@Repository

标识一个受Spring IOC容器管理的持久化层组件

3.业务逻辑层组件:@Service

标识一个受Spring IOC容器管理的业务逻辑层组件

4.表述层控制器组件:@Controller

标识一个受Spring IOC容器管理的表述层控制器组件

组件命名规则

  1. 默认情况:使用组件的简单类名首字母小写后得到的字符串作为beanid
  2. 使用组件注解的value属性指定beanid

注意:事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,@Respository@Service@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。

组件扫描

组件被上述注解标识后还需要通过Spring进行扫描才能够侦测到。

指定被扫描的package:

<context:component-scan base-package="类路径"/>

组件装配

Controller组件中往往需要用到Service组件的实例,Service组件中往往需要用到       Repository组件的实例。Spring可以通过注解的方式帮我们实现属性的装配。

@Autowired

  1. 根据类型实现自动装配。
  2. 构造器、普通字段、一切具有参数的方法都可以应用@Autowired 注解
  3. 默认情况下,所有使用@Autowired注解的属性都需要被设置。当Spring找不到匹 配的bean装配属性时,会抛出异常。
  4. 若某一属性允许不被设置,可以设置@Autowired注解的required属性为 false
  5. 默认情况下,当IOC容器里存在多个类型兼容的bean时,Spring会尝试匹配beanid值是否与变量名相同,如果相同则进行装配。如果beanid值不相同,通过类型的自动装配将无法工作。此时可以在@Qualifier注解里提供bean的名称。Spring甚至允许在方法的形参上标注@Qualifiter注解以指定注入bean的名称。       
  6. @Autowired注解也可以应用在数组类型的属性上,此时Spring将会把所有匹配的bean进行自动装配。
  7. @Autowired注解也可以应用在集合属性上,此时Spring读取该集合的类型信息,然后自动装配所有与之兼容的bean
  8. @Autowired注解用在java.util.Map上时,若该Map的键值为String,那么 Spring将自动装配与值类型兼容的bean作为值,并以beanid值作为键。

@Resource

         @Resource注解要求提供一个bean名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为bean的名称。

@Inject

@Inject@Autowired注解一样也是按类型注入匹配的bean,但没有reqired属性。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!