(1)Spring的ioc底层原理

Spring的IOC操作

什么是ioc操作?

过去我们用new来创建一个对象,ioc操作则是把对象的创建交给spring进行管理

ioc操作的两种方式
  • 配置文件方式
  • 注解方式

IOC的底层原理

ioc底层原理使用的技术
  1. xml配置文件
  2. dom4j解决xml
  3. 工厂设计模式
  4. 反射
image.png
Spring的bean管理(基于配置文件)

Bean实例化的方式

  • 使用类的无参数构造创建(重点)
  • 使用静态工厂创建
  • 使用实例工厂创建

bean标签常用属性

  • id属性
    给这个bean起一个名字(任意命名),作用context.getBean("id")找到该bean
  • class属性
    创建对象所在类的全路径
  • name属性
    功能和id一样,区别在于id属性不能包含特殊符号,name可以包含(但是name已经不常用了)
  • scope属性
    Bean的作用范围,scope常用属性:
  1. singleton:默认值,单例对象
  2. prototype:多例对象
  3. session:创建对象,放到session
  4. globleSession:创建对象,放到全局session
  5. request:创建对象,把对象放到request域

重点是singleton和prototype

singleton详解
我们在配置文件中配置

    //默认是singleton
    

在userServlet中创建两个user对象,并输出这两个对象,观察这两个对象的地址

 public static void main(String args[]){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user1 = (User) context.getBean("user");
        User user2 = (User) context.getBean("user");
        System.out.println(user1);
        System.out.println(user2);
    }

输出结果:


image.png

可见,如果使用singleton,创建的是一个对象

prototype详解
同理,在配置文件中加上

 
    

输出结果:


image.png

可见生成了两个对象

属性注入
1.什么时属性注入:创建对象时,向类的属性设置值
2.属性注入的方式:

  • set方法
  • 有参构造注入
  • 接口注入(很少使用)


    image.png

    在spring框架里面,支持前两种方式

Spring中有参构造的属性注入

public class User {
    private String Uname;
    public String getUname() {
        return Uname;
    }


    public User(String uname) {
        this.Uname = uname;
    }
}

配置文件中


    
//注意,这里name时指的传入构造函数的参数的名字,所以应该时uname不是Uname        

    

Spring中set方法实现属性注入(常用)

public class User {
    public String Uname;
    public void setUname(String uname) {
        Uname = uname;
    }
}

    
    
         

注入对象类型属性(重点)
应用场景:Service类中得到Dao的对象,调用Dao的方法
方法:

  1. 在Service中生成Dao类型的属性
  2. 在Service中生成Dao类型属性的set方法
  3. 在配置文件中完成注入关系
public class UserDao {

    public void add(){
        System.out.println("this is dao");
    }
}

public class UserService {

    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public  void add(){
        System.out.println("this is service");
        userDao.add();
    }

}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class test {
    public static void main(String args []){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userServlet = (UserService) context.getBean("userService");
        userServlet.add();

    }
}

    
    

    
    
        
        
        
    

P名称空间注入
1.在beans标签中添加:

 xmlns:p="http://www.springframework.org/schema/p"

Person类如下:

public class Person {

    private String name;
    public void setName(String name) {
        this.name = name;
    }

    public void Gname(){
        System.out.println(name);
    }
}
  1. 注入Person

     

3.测试结果

public class test {
    public static void main(String args []){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) context.getBean("person");
        person.Gname();
    }
}

image.png

注入复杂类型属性

  1. 数组注入
  2. List注入
  3. Map注入
  4. Properties注入
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class Person {
    private int [] names;
    private List list;
    private Map map;
    private Properties properties;
    public void setNames(int[] names) {
        this.names = names;
    }

    public void setList(List list) {
        this.list = list;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void say(){
        System.out.println(names.length);
        System.out.println(list);
        System.out.println(map);
        System.out.println(properties);
    }
}


    
        
        
            
                1
                2
                2
                2
                2           
            
        
        
        
            
                kevin
                kotlin
            
        
        
        
            
                

                
            
        
        
        
            
                com.mysql.jdbc.driver
            
        
    

输出结果:


image.png
IOC和DI的区别
  • IOC:控制反转,把对象创建交给spring经行配置
  • DI:依赖注入:创建对象的过程中设置对象的属性值
    关系:DI不能单独存在,需在IOC的基础之上完成

你可能感兴趣的:((1)Spring的ioc底层原理)