Spring之IOC底层实现原理

一、Spring框架概述

  1. Spring框架是轻量级的开源的JavaEE框架
  2. Spring框架可以解决企业应用开发的复杂性
  3. Spring框架有两个核心部分:IOC和AOP
  4. Spring框架特点:方便解耦,简化开发;AOP编程支持;方便程序测试;方便和其它框架进行整合;方便事务事务操作;降低API开发难度

IOC概念和原理

1、什么是IOC?

  1. 控制反转,把对象创建和对象之间的调用过程交给Spring框架进行管理
  2. 使用IOC的目的:为了耦合度降低
  3. 做入门案例就是IOC实现

2、IOC底层原理

xml解析——XML有三种解析方式:DOM SAX STAX

存储和传输数据经常一起使用,XML数据通常由程序生成的,用程序解析XML(XML一般不加约束)

 配置文件单独使用(通常会加约束)

工厂模式——把对类的创建初始化全都交给一个工厂来执行,而用户不需要去关心创建的过程是什么样的

反射 ——反射可以在运行时根据指定的类名获得类的信息

3、IOC底层原理的图形解析

第一种图解方式:

Spring之IOC底层实现原理_第1张图片

第二种图解方式(为了避免第一种创建过程中存在耦合度比较高的情况,使用IOC进行创建):

Spring之IOC底层实现原理_第2张图片

4、IOC接口

  1. IOC思想是基于IOC容器完成,IOC容器底层就是对象工厂
  2. Spring框架中对IOC容器实现提供了两种方式(即两种接口)

         2.1 第一种接口(BeanFactory接口):此接口是IOC容器的基本实现,也是Spring框架内部使用的接口,不提供给开发人员进行使用

注:此接口是在加载配置文件时不会创建对象,而是在获取对象或使用时才去创建对象

        2.2 第二个接口(ApplicationContext):此接口是BeanFactory接口的子接口,提供了更强大的功能,一般由开发人员进行

注:此接口在加载配置文件时就会创建配置文件中所配置的对象

5、ApplicationContext接口的所有实现类

Spring之IOC底层实现原理_第3张图片

6、IOC操作Bean管理(基于xml配置文件方式实现Spring框架中创建对象和注入属性)

6.1 Spring框架中对象的创建

第一步:基于xml方式创建对象


  1. 在Spring框架配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象的创建
  2. 在bean标签中有很多属性,常用的属性介绍:id属性——唯一标识   class属性——类全路径
  3. 创建对象时默认执行无参构造方法完成对象的创建

6.2 Spring框架中对一个对象中的属性进行注入

介绍注入属性之前,先介绍一下DI——就是依赖注入,也是属性注入

第一种注入的方式使用set方法进行注入

第一步:创建类,定义属性和对应的set方法

/** 
* 演示使用set方法进行注入属性 
*/ 
public class Book { 
    //创建属性 
    private String bname; 
    private String bauthor; 

    //创建属性对应的set方法 
    public void setBname(String bname) { 
        this.bname = bname; 
    } 
    public void setBauthor(String bauthor) { 
        this.bauthor = bauthor; 
    } 
}

第二步:在Spring配置文件中创建对象,然后配置属性注入

 

     
     
     

第二种属性注入方式:使用有参构造进行注入

第一步:创建类,定义属性,创建属性对应的有参构造方法

/** 
* 使用有参数构造注入
*/ 
public class Orders { 
    //属性 
    private String oname; 
    private String address; 
    //有参数构造 
    public Orders(String oname,String address) { 
        this.oname = oname; 
        this.address = address; 
    } 
}

第二步在Spring配置文件中进行配置

 
 
     
     

第三种注入方式是引入p名称空间进行属性的注入

第一步:在配置文件中添加p名称空间

第二步进行属性注入

 

第四种是其它类型属性的注入

第一种是null值的注入

 
 
     

第二种是属性值包含特殊符号

 
 
    >]]> 

第三种是对象的注入(外部bean)

public class UserService { 
    //创建UserDao类型属性,生成set方法 private UserDao userDao; 
    public void setUserDao(UserDao userDao) { 
        this.userDao = userDao; 
    } 
    public void add() { 
        System.out.println("service add..............."); 
        userDao.update(); 
    } 
}
 
 
     
     
 

第四种对象的注入(内部)

//部门类 
public class Dept { 
    private String dname; 
    public void setDname(String dname) { 
        this.dname = dname; 
    } 
} 

//员工类 
class Emp { 
    private String ename; 
    private String gender; 
    //员工属于某一个部门,使用对象形式表示 
    private Dept dept; 
    public void setDept(Dept dept) { 
        this.dept = dept; 
    } 
    public void setEname(String ename) { 
        this.ename = ename; 
    } 
    public void setGender(String gender) { 
        this.gender = gender;
    } 
}
 
 
     
     
     
     
     
         
             
         
    

第五种集合的注入

public class Stu { 
    //1 数组类型属性 
    private String[] courses; 

    //2 list集合类型属性 
    private List list; 

    //3 map集合类型属性 
    private Map maps; 

    //4 set集合类型属性 
    private Set sets; 

    public void setSets(Set sets) { 
        this.sets = sets; 
    } 
    public void setCourses(String[] courses) { 
        this.courses = courses; 
    } 
    public void setList(List list) { 
        this.list = list; 
    } 
    public void setMaps(Map maps) { 
        this.maps = maps; 
    } 
}

        
            
                java课程01
                java课程02
            
        
        
            
                张三
                李四
            
        
        
            
                
                
            
        
        
            
                MySql
                Web
            
        


        
            
                
                
            
        
    


    
        
    
    
        
    

6.3 bean的作用域

  1. 在Spring里面,设置创建bean实例是单实例还是多实例
  2. 在Spring里面,默认情况下,bean是单实例
 @Test
    public void test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "bean_01.xml");
        Stu stu1 = context.getBean("stu", Stu.class);
        Stu stu2 = context.getBean("stu", Stu.class);
        System.out.println(stu1);
        System.out.println(stu2);
    }

Spring之IOC底层实现原理_第4张图片

如何设置多实例?

  1. 在Spring配置文件bean标签中有属性scope用于设置单实例还是多实例
  2. 默认值——singleton(单实例)  prototype(多实例)

单实例和多实例的区别?

  • 单实例是在加载Spring配置文件时候就会创建单实例对象
  • 多实例不是在加载配置文件时创建对象,而是在调用getBean方法时创建对象

6.4 bean的生命周期

  1. 生命周期——指对象从创建到销毁的过程
  2. bean的生命周期
  • 通过构造器创建bean实例(无参构造)
  • 为bean的属性设置值和对其他bean引用(使用set方式注入)
  • 调用bean的初始化方法(需要配置)
  • 获取bean对象
  • 当容器关闭时,销毁(需要配置)
public class Orders {
    //无参数构造 
    public Orders() { 
        System.out.println("第一步 执行无参数构造创建bean实例"); 
    } 
    private String oname; 
    public void setOname(String oname) { 
        this.oname = oname; 
        System.out.println("第二步 调用set方法设置属性值"); 
    } 
    //创建执行的初始化的方法 
    public void initMethod() { 
        System.out.println("第三步 执行初始化的方法"); 
    } 
    //创建执行的销毁的方法 
    public void destroyMethod() { 
        System.out.println("第五步 执行销毁的方法"); 
    } 
}

 
     


@Test 
public void testBean3() { 
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Orders orders = context.getBean("orders", Orders.class); 
    System.out.println("第四步 获取创建bean实例对象"); 
    System.out.println(orders); 
    //手动让bean实例销毁 
    context.close(); 
}

7、基于注解实现IOC操作Bean管理

7.1 什么是注解?

  1. 注解是代码的特殊标记,格式形如(属性名称=属性值....)
  2. 使用注解,注解可作用在类上面,方法上面,属性上面

7.2 Spring针对bean管理中创建对象提供的注解

  1. @Commponent
  2. @Service——一般使用在Service层
  3. @Controller——一般使用在Web层
  4. Repository——一般使用在Dao层

第一步:引入依赖

第二步:开启组件扫描

 

第三步:创建类,在类上面添加创建对象注解

//在注解里面value属性值可以省略不写, 
//默认值是类名称,首字母小写 
//UserService -- userService
@Component(value = "userService") // 
public class UserService { 
    public void add() { 
        System.out.println("service add......."); 
    } 
}

7.3 使用注解方式实现属性的注入

@Autowired:根据属性类型进行自动装配

@Service 
public class UserService { 
    //定义dao类型属性 
    //不需要添加set方法
    //添加注入属性注解 
    @Autowired 
    private UserDao userDao; 
    public void add() { 
        System.out.println("service add......."); 
        userDao.add(); 
    } 
}

@Qualifier:根据名称进行注入
这个@Qualifier注解的使用,和上面@Autowired一起使用 

//定义dao类型属性 
//不需要添加set方法
//添加注入属性注解 
@Autowired 
//根据类型进行注入 因为userDao接口的实现类可以有很多个
@Qualifier(value = "userDaoImpl1") 
//根据名称进行注入 
private UserDao userDao;

@Resource:可以根据类型注入,可以根据名称注入

//@Resource //根据类型进行注入 
@Resource(name = "userDaoImpl1") 
//根据名称进行注入 
private UserDao userDao;

@Value:注入普通类型属性

@Value(value = "abc") 
private String name;

 

你可能感兴趣的:(spring,bean,spring,boot)