Spring IoC(反转控制)

spring 是什么

Spring框架是由于软件开发的复杂性而创建的,它是分层的 Java SE/EE应用 full-stack 轻量级开源框架。

它以 IoC(Inverse Of Control: 反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多 著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。

spring 的优势

方便解耦,简化开发
通过 Spring提供的 IoC容器,可以将对象间的依赖关系交由 Spring进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

AOP编程的支持
通过 Spring的 AOP 功能,方便进行面向切面的编程,许多不容易用传统OOP 实现的功能可以通过 AOP 轻松应付。

声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理, 提高开发效率和质量。

方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

方便集成各种优秀框架
Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz 等)的直接支持。

降低 JavaEE API的使用难度
Spring对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。

spring 的体系结构

Spring IoC(反转控制)_第1张图片


今天我们只讲解Spring的IoC(反转控制)。

使用 spring的 IoC解决程序耦合

Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。

下面我们通过spring IoC来实现之前工厂模式的案例
持久层接口IStudentDao

package dao;
/**
 * 持久层接口
 */
public interface IStudentDao {
    /**
     * 模拟查询所有
     */
    void findAll();
}

持久层实现类StudentDaoImpl

package dao.impl;
import dao.IStudentDao;

/**
 * 持久层实现类
 */
public class StudentDaoImpl implements IStudentDao {
    @Override
    public  void findAll(){
        System.out.println("查找到所有学生记录。");
    }
}

业务逻辑层接口IStudentService

package service;
/**
 * 业务层的接口
 */
public interface IStudentService {
    /**
     * 模拟查询
     */
    void findAll();
}

业务逻辑层实现类StudentServiceImpl

package service.impl;
import dao.IStudentDao;
import dao.impl.StudentDaoImpl;
import service.IStudentService;
/**
 * 业务层实现类
 */
public class StudentServiceImpl implements IStudentService {

    private IStudentDao studentDao;
    @Override
    public void  findAll(){
        studentDao.findAll();
    }
}

基于 XML 的配置

在类的根路径下创建一个任意名称的 xml 文件,让 spring 管理资源,在配置文件中配置 service 和 dao
bean.xml


<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="studentServiceImpl" class="service.impl.StudentServiceImpl">
        <property name="studentDao" ref="studentDao">property>
    bean>
    <bean id="studentDao" class="dao.impl.StudentDaoImpl">bean>
beans>

IOC 中 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. 
 
init-method:指定类中的初始化方法名称。  
destroy-method:指定类中销毁方法名称。 

bean 的作用范围和生命周期

单例对象:scope="singleton"   
	一个应用只有一个对象的实例。它的作用范围就是整个引用。   
	生命周期:    
		对象创建:当应用加载,创建容器时,对象就被创建了。    
		对象存活:只要容器在,对象一直活着。    
		对象销毁:当应用卸载,销毁容器时,对象就被销毁了。  
多例对象:scope="prototype"   
	每次访问对象时,都会重新创建对象实例。   
	生命周期:    
		对象创建:当使用对象时,创建新的对象实例。    
		对象存活:只要对象在使用中,就一直活着。    
		对象销毁:当对象长时间不用时,被 java 的垃圾回收器回收了。 

spring 的依赖注入

 spring中的依赖注入
        依赖注入:
            Dependency Injection
        IOC的作用:
            降低程序间的耦合(依赖关系)
        依赖关系的管理:
            以后都交给spring来维护
        在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明
         依赖注入:
            能注入的数据:有三类
                基本类型和String
                其他bean类型(在配置文件中或者注解配置过的bean)
                复杂类型/集合类型
             注入的方式:有三种
                第一种:使用构造函数提供
                第二种:使用set方法提供
                第三种:使用注解提供

构造函数注入

使用的标签:constructor-arg
标签出现的位置:bean标签的内部
标签中的属性
    type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
    index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
    name:用于指定给构造函数中指定名称的参数赋值                                        常用的
    value:用于提供基本类型和String类型的数据
    ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
    优势:
        在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
    弊端:
        改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
示例:
<bean id="testbean" class="Testbean">
    <constructor-arg name="name" value="jack">constructor-arg>
    <constructor-arg name="age" value="18">constructor-arg>
bean>

set方法注入

标签:property
    出现的位置:bean标签的内部
    标签的属性
        name:用于指定注入时所调用的set方法名称
        value:用于提供基本类型和String类型的数据
        ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
    优势:
        创建对象时没有明确的限制,可以直接使用默认构造函数
    弊端:
        如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
示例:
	<bean id="testbean" class="Testbean">
        <property name="name" value="jack" >property>
        <property name="age" value="18">property>
    bean>        

复杂类型的注入/集合类型的注入

用于给List结构集合注入的标签:
   list array set
用于个Map结构集合注入的标签:
    map  props
嵌套在property中使用
示例:
	 <bean id="testbean" class="Testbean">
        <property name="mySet">
            <set>
                <value>Avalue>
                <value>Bvalue>
            set>
        property>
        <property name="myArray">
            <array>
                <value>Avalue>
                <value>Bvalue>
            array>
        property>
        <property name="myList">
            <list>
                <value>Avalue>
                <value>Bvalue>
            list>
        property>
        <property name="myMap">
            <props>
                <prop key="key1">1prop>
                <prop key="key2">2prop>
            props>
        property>
        <property name="myProps">
            <map>
                <entry key="key1" value="1">entry>
            map>
        property>
    bean>

测试代码

package ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.IStudentService;
import service.impl.StudentServiceImpl;

public class Client {

    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        IStudentService as  = (StudentServiceImpl)ac.getBean("studentServiceImpl");
        IStudentService as1  = (StudentServiceImpl)ac.getBean("studentServiceImpl");
        as.findAll();
        // 判断对象是否单例
        System.out.println(as==as1);
    }
}

运行结果如下:

查找到所有学生记录。
true

今天的分享就到这里了,希望大家能够有所收获,欢迎关注。

你可能感兴趣的:(spring)