Spring-01 概念&反转控制IOC&依赖注入DI

1.Spring概述

1.1 spring是什么?

Spring是分层的java应用jull-stack轻量级框架,以**Ioc和AOP**为核心,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合众多第三方框架和类库。

1.2 spring优势

1. 方法解耦,简化开发
    通过Ioc容器,可以将对象间的依赖关系交给Spring控制,避免硬编码造成的程序耦合。用户也不必为单例模式、属性文件解析等低层代码今昔编写。
2. AOP编程支持
    通过AOP的工厂,方便进行面向切面编程,许多功能可以轻易通过AOP实现。
3. 声明式事务的支持
    可以从事务管理代码中解脱出来,通过声明式事务的管理,提高开发效率和质量。
4. 方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。 
5. 方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz 等)的直接支持
6. 降低java ee API使用难度
Spring对JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低
7. 源码高大上 值得学习
Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。 

1.3 spring 体系结构

![](https://img2018.cnblogs.com/blog/1882316/202002/1882316-20200211194758395-1508272279.png)

2 IOC的概念和作用

2.1 什么是程序的耦合

耦合度:模块之间的关联度。
模块间的耦合度值模块之间的依赖关系,包括控制关系、调用关系、传递数据关系。模块间联系越多,耦合性越强,维护成本越高。
开发中,有些依赖关系是必需的,有些依赖关系可以通过代码优化解除。
如下:编译期的依赖关系应该解决。
![](https://img2018.cnblogs.com/blog/1882316/202002/1882316-20200212133847808-492214337.png)

2.2 工厂模式解耦

实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。 

2.2.1 控制反转 IOC

IOC的作用:消除代码中的依赖关系。
利用工厂创建对象存入容器中。

3 spring的ioc解决程序耦合

3.0 Bean的概念

Bean:在计算机英语中,有可重用组件的含义。
JavaBean:用java语言编写的可重用实体类。   范围:javabean  > 实体类

3.1 基于XML配置的基本使用


    1.导入相关jar包 或 坐标
    2.在类的根路径虾创建一个**任意名称**的xml文件
    约束如下:
<?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"> </beans> 

    3.让spring管理资源 配置要存入ioc容器的对象
    <bean>标签:用于配置spring创建对象,并存入ioc容器中
        id属性:对象的唯一表示
        class属性:要创建对象的全限定类名
    如:<bean id="user" class="com.sweetbetter.domain.User"></bean>
    4.测试
    4.1 获取spring容器 详细的后面讲到
        ApplicationContext ac= new ClassPathXmlApplicationContext("bean.xml");
    4.2 根据id获取对象
        User u=ac.getBean("user",User.class);    

3.2 基于XML配置的细节

3.2.1 spring中工厂类的结构

3.2.2 获取容器的三种

ApplilcationContext接口的三个实现类
    1.ClassPathXmlApplicationContext:从类的根路径下加载配置文件 **推荐使用**
    2.FileSystemXmlApplicationContext:使用的是系统的路径
    3.AnnotationConfigApplicationContext:使用注解配置容器对象时,使用此类来创建spring容器

3.2.3 BeanFactory和ApplicationContext的区别

BeanFactory(顶层接口):采用的策略时延迟加载的。什么时候根据id获取对象,什么时候才真正的创建对象。(多例对象适用)
ApplicationContext :是BeanFactory的子接口。在构建核心容器时,创建对象采取的策略时默认立即加载的方式。即读取完配置文件就以将配置文件中配置的对象创建了。(单例对象适用) 实际开发更多使用这个接口。当然Spring是强大的,可以配置是立即还是延迟加载。

3.2.4 bean标签细节

 bean标签:
    作用:配置对象让spring读取并创建
    **默认情况:**它调用的是无参的构造方法创建,如果没有无参的构造方法且没配置其他创建方式,就不能创建成功。
    属性:
        id:给对象在容器提供一个唯一标识。
        class:指定类的全限定类名。用于反射创建对象,默认使用无参构造函数。
        scope:指定对象的作用范围
            * **singleton:** 默认值 单例的 一个应用只有一个对象的实例
            * **prototype:** 多例的 每次访问对象时,都会重新创建对象实例
            * request:WEB项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
            * session:WEB项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
            * global session:WEB项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么 globalSession 相当于 session,应用场景如:实现负载均衡的服务器中,第一次请求返回了验证码,第二次提交验证码,是另一台服务器接收的请求,此在服务器没有验证码如何比对?这就用到了golbal session。
        init-method:指定类中初始化方法名称
        destory-method:指定类中销毁方法名称
        factory-method:指定创建bean的方法名称
        factory-bean:指定工厂的bean id

3.2.5 实例化bean的三种方法

第一种:
    <!--默认情况下:
    它会默认无参构造函数创建对象。如果bean中没有默认午餐构造函数,将会创建失败。-->
    <bean id="exmaple" class="com.sweetbetter.user"/>
第二种:
    <!--spring管理静态工厂,使用静态工厂的方法创建对象
    如StaticFactory中有一个静态方法createInstance创建对象,无需先有工厂实例 
    -->
    <bean id="exmaple" class="com.sweetbetter.StaticFactory" 
          factory-method="createInstance"></bean>
第三种:
    <!--spring管理实例工厂,使用实例工厂的方法创建对象
    此方法:先把工厂的创建交给spring管理,然后再由工厂的bean来调用里面的方法。如工厂类名:InstanceFactory  创建实例的方法:createUser
    -->
    <bean id="instanceFactory" class="com.sweetbetter.InstanceFactory"></bean>
<bean id="user" factory-bean="instanceFactory" factory-method="createUser"></bean>

3.2.6 bean的作用范围和生命周期

单例对象:
一个应用只有一个对象的实例。它的作用范围就是整个引用。 
出生:当容器创建时
活着:容器还在就在
死亡:容器销毁,对象消亡
总结:和容器同生共死
多例对象:
每次访问对象时,都会重新创建对象实例。 
出生:当使用时创建
活着:使用的过程中就一直活着
死亡:java的垃圾回收器回收

4 Spring的依赖注入

依赖注入:DI(Dependency Injection),他是Spring框架核心ioc的具体体现。
上面讲的是通过反转控制把对象创建交给了spring,但代码中不可能没有依赖的情况,如业务层还要调用持久层的方法,即要 new 持久层的类。
依赖注入DI要解决的就是这种情况。简单的说,就是等框架把持久层的对象传入业务层。

4.1 使用依赖注入

4.1.1 使用构造函数注入

第一种:使用构造函数注入
  <!--使用构造函数:
    要求:类中需要提供一个对应参数列表的构造函数
    涉及标签:constructor-arg 
        属性:index type name:用来找给谁赋值的
        value:赋值基本类型和String 
                ref:赋值其他bean类型
    下面的value是字符串,类中age的类型是Interge,spring会自动转换
    -->
<bean id="user" class="com.sweetbetter.user">
   <constructor-arg name="name" value="张三"></constructor-arg>   
   <constructor-arg name="age" value="18"></constructor-arg>     
   <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<bean id="now" class="java.util.Date"></bean>

4.1.2 使用set方法注入

第二种:使用set方法注入(更常用)
<!--要求:要在类中提供set方法
    标签:property
    属性:name:找的是类中set方法后面的部分 
             ref:给属性赋值是其他 bean 类型的 
             value:给属性赋值是基本数据类型和string类型的 
    -->
<bean id="User" class="xxxx">
        <property name="name" value="xxx"></property>
         <property name="age" value="21"></property>
         <property name="birthday" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean> 

4.1.3 注入集合属性(array,list,set,map,props,entry)

注入集合属性:是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。
<!-- 注入集合数据   
    List 结构的:   array,list,set 
    Map 结构的   map,entry,props,prop 
--> 
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> 
 <!-- 在注入集合数据时,只要结构相同,标签可以互换 -->
  <!-- 给数组注入数据 -->  
    <property name="myStrs"> 
        <set>    
          <value>AAA</value>    
          <value>BBB</value>    
          <value>CCC</value>  
        </set> 
     </property> 
    
 <!-- 注入 list 集合数据 --> 
    <property name="myList">  
        <array>    
            <value>AAA</value>
            <value>BBB</value>    
            <value>CCC</value>  
        </array> 
    </property> 
    
 <!-- 注入 set 集合数据 -->  
    <property name="mySet">
     <list>
          <value>AAA</value>   
          <value>BBB</value>  
          <value>CCC</value>   
       </list>  
    </property> 
 <!-- 注入 Map 数据 -->  
   <property name="myMap">   
       <props> 
           <prop key="testA">aaa</prop>  
           <prop key="testB">bbb</prop>   
       </props> 
 </property> 
 <!-- 注入 properties 数据 --> 
 <property name="myProps"> 
      <map>    
          <entry key="testA" value="aaa"></entry> 
         <entry key="testB">    
            <value>bbb</value> 
        </entry>  
     </map> 
    </property> 
</bean> 

猜你喜欢

转载自www.cnblogs.com/sweetbetter/p/12298772.html
今日推荐