• spring学习第二天_Spring Ioc(1)


    1.IoC的概念

    1. IoC控制反转(IoC,Inversion of Control),
      是一个概念,是一种思想。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。
    2. DI依赖注入:Dependency Injection。
      依赖注入 DI 是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。依赖注入是目前最优秀的解耦方式。依赖注入让Spring的Bean之间以配置文件的方式组织在一起,而不是以硬编码的方式耦合在一起的。
    3. IoC与DI的关系
      IoC是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式之一是DI。

    SpringIoC 类似于 包子铺, 对象就是包子
    IoC:控制反转,本质就是将对象new的过程交给了Spring容器去处理。

    2.IoC基于XML配置的实现方式

    2.1 基本实现步骤
    演示第一个SpringIoC案例
    2.1.1 创建一个普通的Java项目
    在这里插入图片描述
    2.1.2 导入相关的Spring依赖
    将我们需要使用到的相关的jar拷贝到lib目录下,选中jar包点击右键,Build Path->Add to Build Path,将jar包添加到Referenced Libraries下面。
    在这里插入图片描述
    2.1.3 创建Spring配置文件
    在src目录下创建一个applicationContext.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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.1.4 添加对应的Java类型
    Food.java

    package com.zyz.spring;
    
    public class Food {
    
    	public Food(String name) {
    		super();
    		this.name = name;
    	}
    
    	private String name;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	@Override
    	public String toString() {
    		return "Food [name=" + name + "]";
    	}
    	
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    Person.java

    package com.zyz.spring;
    
    public class Person {
    
    	private String name;
    	private int age;
    	private Food food;
    	
    	
    	public Person(String name, int age, Food food) {
    		super();
    		this.name = name;
    		this.age = age;
    		this.food = food;
    	}
    	
    	
    	public Food getFood() {
    		return food;
    	}
    	public void setFood(Food food) {
    		this.food = food;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + ", food=" + food + "]";
    	}
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    2.1.5 配置文件中注册Bean
    将Person在配置文件中通过bean标签注册
    引入外部文件

    <import resource="application-service.xml"/>
    
    • 1

    applicationContext.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">
    
    		<import resource="applicationContext-*.xml"/>
            //通过构造器进行注入属性的值
            <bean id="person" class="com.zyz.spring.Person">
            	<constructor-arg name="name" value="maxiaosan"></constructor-arg>
            	<constructor-arg name="age" value="18"></constructor-arg>
            	<constructor-arg name="food" ref="food"></constructor-arg>
            </bean>
          
            
    </beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    applicationContext-service.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">
    
            
       //通过构造器进行注入属性的值
            <bean id="food" class="com.zyz.spring.Food">
            <constructor-arg name="name" value="jiaozi"></constructor-arg>
            </bean>
            
            
    </beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.1.6 Java代码实现

    package com.zyz.spring;
    
    import org.apache.commons.lang3.builder.ToStringBuilder;
    import org.apache.commons.lang3.builder.ToStringStyle;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class TestGetBean {
    	public static void main(String[] args) {
    	// IoC的初始化操作
    		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    		// 从容器中获取person对象
             Person person = (Person)ctx.getBean("person");
    		
    		System.out.println(person.toString());
    		System.out.println(person.getFood().toString());
    		System.out.println("========"+ToStringBuilder.reflectionToString(person,ToStringStyle.MULTI_LINE_STYLE));;
    		System.out.println("====------===="+ToStringBuilder.reflectionToString(ctx,ToStringStyle.MULTI_LINE_STYLE));;
    		
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    输出

    Person [name=zhangwuji, age=18, food=Food [name=jiaozi]]
    ========com.zyz.spring.Person@35d176f7[
      name=zhangwuji
      age=18
      food=Food [name=jiaozi]
    ]
    ====------====org.springframework.context.support.ClassPathXmlApplicationContext@c4437c4[
      configResources=<null>
      validating=true
      configLocations={applicationContext.xml}
      setIdCalled=false
      allowBeanDefinitionOverriding=<null>
      allowCircularReferences=<null>
      beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@3567135c: defining beans [food,person]; root of factory hierarchy
      beanFactoryMonitor=java.lang.Object@a7e666
      logger=org.apache.commons.logging.impl.Jdk14Logger@68bbe345
      id=org.springframework.context.support.ClassPathXmlApplicationContext@c4437c4
      displayName=org.springframework.context.support.ClassPathXmlApplicationContext@c4437c4
      parent=<null>
      environment=StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[MapPropertySource {name='systemProperties'}, SystemEnvironmentPropertySource {name='systemEnvironment'}]}
      beanFactoryPostProcessors=[]
      startupDate=1661869012782
      active=true
      closed=false
      startupShutdownMonitor=java.lang.Object@7c29daf3
      shutdownHook=<null>
      resourcePatternResolver=org.springframework.core.io.support.PathMatchingResourcePatternResolver@9660f4e
      lifecycleProcessor=org.springframework.context.support.DefaultLifecycleProcessor@5a8806ef
      messageSource=Empty MessageSource
      applicationEventMulticaster=org.springframework.context.event.SimpleApplicationEventMulticaster@5e853265
      applicationListeners=[]
      earlyApplicationListeners=[]
      earlyApplicationEvents=<null>
      classLoader=sun.misc.Launcher$AppClassLoader@73d16e93
      protocolResolvers=[]
      resourceCaches={}
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    getBean方法
    我们从IoC容器中获取对应的对象是通过getBean方法实现的,默认是调用的无参构造方法。

    上面使用的是构造函数的形式,下面使用属性注入的方式来给属性初始化赋值

    	<import resource="applicationContext-*.xml"/>
            <!-- 对象属性 Spring 会调起 对象的 set方法  来 DI -->
            <bean id="person" name="human,star" class="com.mashibing.spring.Person">
            	<property name="name"><value>马小六</value></property>
            	<property name="age" value="18" />
            	<property name="food" ref="food" />
            </bean>
            <!-- 如果配置文件有一个class多个bean,代码通过bean的class属性获取就会报错 -->
             <bean id="p1"  class="com.zyz.spring.Person"></bean>
             
            <bean id="food" class="com.zyz.spring.Food"></bean>
            
           <alias name="person" alias="person2"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    getBean获取对象实例的方法:id;name;class;id+class混合

    	ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    		Person person1 = (Person)ctx.getBean("star");//通过name获取
    		Person person2 = (Person)ctx.getBean("person");//通过id获取
    		//Person person3 = (Person)ctx.getBean(Person.class);//通过class类获取
    		//通过class类获取   属性没有初始化 所以基本类型是默认值 引用类型是null 
    		Person person4 = (Person)ctx.getBean("p1",Person.class);
    		System.out.println(ToStringBuilder.reflectionToString(person4));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    组合的方式查找
    Person person4 = (Person)ctx.getBean(“p1”,Person.class);

    通过属性赋值,如果实体类没有set方法,会报错

    Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'name' of bean class [com.zyz.spring.Person]: Bean property 'name' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    
    • 1

    IoC对象工厂注入

    静态工厂注入
    通过工厂类的静态方法获取对应的实例对象

    在配置文件中bean标签加工厂方法

      <bean id="p1"  class="com.zyz.spring.Person" factory-method="getInstance"></bean>
    
    • 1

    在实体类添加静态方法

    public static Person getInstance() {
    		Person p = new Person("sun", 19, new Food("niurou"));
    		return p;
    	}
    
    • 1
    • 2
    • 3
    • 4

    通过getBean方法生成的实体类对象就是上面静态方法new出的对象

    	ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    Person person4 = (Person)ctx.getBean("p1");
    	
    		Person person5 = (Person)ctx.getBean("p1");
    		System.out.println(person4.toString());
    		System.out.println(person4==person4);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    生成的两个对象是同一个对象

    动态工厂注入
    通过工厂类的普通方法获取实例对象
    配置文件

    <!-- 注册动态工厂Bean -->
     <bean class="com.zyz.spring.userDynamicFactory" id="userDynamicFactory" />
     <!-- 从工厂对象获取User对象 -->     
     <bean id="user"  factory-bean="userDynamicFactory" factory-method="getInstance"></bean>
    
    • 1
    • 2
    • 3
    • 4

    userDynamicFactory.java

    public class userDynamicFactory {
    	public Person getInstance(){Person p = new Person("sun2", 19, new Food("niurou"));
    	return p;}
    }
    
    • 1
    • 2
    • 3
    • 4
    		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    		Person person6= (Person)ctx.getBean("user");
    		System.out.println(person6.toString());
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    buildroot中C语言使用libconfig的实例
    C语言常见题目 过关斩将(1)C语言的那些坑题,你可知道❓
    理论第九课——进制转换(八进制篇)
    设计师资格证
    1989-2020中国省级平均受教育年限与学历结构数据
    MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(3)-系统数据集合设计
    淘宝双11数据分析与预测课程案例中(林子雨)错误点总结
    Node.js 实战 第2章 Node 编程基础 2.3 用module.exports 微调模块的创建
    Jemeter实现多用户登录的两种方式
    AI时代新爬虫:网站自动转LLM数据,firecrawl深度玩法解读
  • 原文地址:https://blog.csdn.net/qq_37200262/article/details/126593725