当前位置: 首页 > news >正文

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>

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 + "]";
	}
	
	
}

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 + "]";
	}
	
}

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

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

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>

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>

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));;
		
	}
}

输出

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={}
]

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"/>

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类获取  <bean id="p1"  class="com.mashibing.spring.Person"></bean> 属性没有初始化 所以基本类型是默认值 引用类型是null 
		Person person4 = (Person)ctx.getBean("p1",Person.class);
		System.out.println(ToStringBuilder.reflectionToString(person4));

组合的方式查找
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?

IoC对象工厂注入

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

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

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

在实体类添加静态方法

public static Person getInstance() {
		Person p = new Person("sun", 19, new Food("niurou"));
		return p;
	}

通过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);

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

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

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

userDynamicFactory.java

public class userDynamicFactory {
	public Person getInstance(){Person p = new Person("sun2", 19, new Food("niurou"));
	return p;}
}
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

		Person person6= (Person)ctx.getBean("user");
		System.out.println(person6.toString());

相关文章:

  • 22-08-30 西安JUC(03) Callable接口、阻塞队列4套方法、ThreadPool线程池
  • React(8)-组件ref
  • 2022/8/30
  • picoCTF - Day 1 - Warm up
  • 前端面试题之组件
  • 自己动手写编译器:词法解析的系统化研究
  • 【程序员面试金典】01.02. 判定是否互为字符重排
  • go实现剑指offer
  • 【Go-Lua】Golang嵌入Lua代码——gopher-lua
  • yolov5+shufflenet轻量化目标检测
  • 【BurpSuite】插件开发学习之J2EEScan(上)-被动扫描
  • java计算机毕业设计企业公开招聘系统源码+数据库+系统+lw文档+mybatis+运行部署
  • 赛事开源Baseline参考目录格式
  • C++设计模式之Bridge桥模式
  • Kibana-8.4.0-Linux安装
  • 【Leetcode】101. 对称二叉树
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • Akka系列(七):Actor持久化之Akka persistence
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • ES6之路之模块详解
  • hadoop集群管理系统搭建规划说明
  • JavaScript-Array类型
  • linux学习笔记
  • mysql_config not found
  • Python 反序列化安全问题(二)
  • REST架构的思考
  • spring boot下thymeleaf全局静态变量配置
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 聊聊directory traversal attack
  • 配置 PM2 实现代码自动发布
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 鱼骨图 - 如何绘制?
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • 阿里云ACE认证学习知识点梳理
  • ​比特币大跌的 2 个原因
  • ​插件化DPI在商用WIFI中的价值
  • #stm32整理(一)flash读写
  • #WEB前端(HTML属性)
  • #宝哥教你#查看jquery绑定的事件函数
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (转)iOS字体
  • (转)Oracle存储过程编写经验和优化措施
  • *1 计算机基础和操作系统基础及几大协议
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .gitignore文件_Git:.gitignore
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET大文件上传知识整理
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递