SpringIoc创建与使用的大致步骤
SpringIoC的创建与使用过程分为3步
编辑
1.编写配置信息(编写XML,注解、Java类)
2.创建IoC容器(实例化Ioc对象)
3.从Java代码中获取组件并使用
一.基于xml配置SpringIoc
实现过程思路:
编辑
1.配置SpringIoc的jar包依赖
<!-- SpringIoc核心jar包 包含core ioc breans 等 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!-- junit5测试 --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.3.1</version> <!-- 使用属性引用JUnit Jupiter版本 --> <scope>test</scope> </dependency>
2.编写xml配置文件(配置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>
由于SpringIoc是存放组件的容器,而组件内容是可重复使用的对象。在xml中<bean>标签就是代表着组件
3.三种创建组件的方式
不同的创建组件的方式,对应的xml配置也不同。下面介绍三种创建组件的方式,无参构造方式创建组件,静态工厂创建、非静态工厂创建
1.无参构造方式创建组件
当通过构造函数方法创建一个bean(组件对象) 时,所有普通类都可以由 Spring 使用并与之兼容。也就是说,正在开发的类不需要实现任何特定的接口或以特定的方式进行编码。只需指定 Bean 类信息就足够了。但是,默认情况下,我们需要一个默认 (空)构造函数。
无参构造对象代码案例
package com.alphamilk.Ioc; //无参构造类 public class wucanTemp { public void doWork(){ System.out.println("调用无参构造方法doWork函数"); } }
对应的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:组件的唯一标识,不可重复 class:组件通过反射创建,所以需要类的权限定符 配置完一个组件相当于new了一个wucanTemp对象 --> <bean id="wucanTemp" class="com.alphamilk.Ioc.wucanTemp"/> </beans>
编辑
2.静态工厂创建组件
静态工厂代码:
package com.alphamilk.Ioc; //静态工厂代码 public class HelloTemp { private HelloTemp(){} public static HelloTemp getHelloTemp(){ HelloTemp temp = new HelloTemp(); return temp; } }
对应XML配置:
<!-- 静态工厂的组件配置 <bean 一个组件信息,一个组件对象 ,一个工厂静态方法 id:组件的唯一标识 class:类的权限定符 factory-method:工厂的静态方法 --> <bean id="helloTemp" class="com.alphamilk.Ioc.HelloTemp" factory-method="getHelloTemp"/>
编辑
3.非静态工厂创建组件
package com.alphamilk.Ioc; //非静态工厂 public class FactoryNoStatic { private static FactoryNoStatic factoryNoStatic = new FactoryNoStatic(); public FactoryNoStatic getInstance(){ return factoryNoStatic; } }
对应的XML配置
<!-- 3非静态工厂配置组件--> <!-- 3.1配置工厂类的组件信息--> <bean id="factoryNoStatic" class="com.alphamilk.Ioc.FactoryNoStatic"/> <!-- 3.2通过指定非静态工厂对象和方法名来配置生成的ioc信息--> <bean id="factoryNoStatic2" factory-bean="factoryNoStatic" factory-method="getInstance"/>
编辑
二.基于xml配置DI
DI(依赖注入)有两种实现方式
第一种通过构造函数实现,另一种是通过setter实现,两种不同的方式实现对应的xml配置也有所不同。下边分别介绍每种的配置。
1.基于构造函数实现对象
基于构造函数的 DI 是通过容器调用具有多个参数的构造函数来完成的,每个参数表示一个依赖项下面的示例演示一个只能通过构造函数注入进行依赖项注入的类!
基于单参构造方法
类对象案例:
package com.alphamilk.loc2; public class UserDao { } public class UserService { private UserDao userDao = new UserDao(); private String name; private int age; // 单参构造方法 UserService(UserDao userDao){ this.userDao = userDao; } // 多参构造方法 UserService(String name,int age,UserDao userDao){ this.name=name; this.age = age; this.userDao = userDao; } }
单参构造方法下,DI(依赖注入)的配置
<?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"> <!-- 单参数构造方法--> <!-- 步骤1:将对象都存放在IOc容器中--> <bean id="userDao" class="com.alphamilk.loc2.UserDao"/> <!-- 构造参数传递di的配置 <constructor-org 构造参数传值的di配置 value=直接属性值 ref = 引用其它的bean组件,传入bean的id值 --> <bean id="service" class="com.alphamilk.loc2.UserService"> <constructor-arg ref="userDao"/> </bean> </beans>
多参情况下DI(依赖注入)对应xml配置
<!-- 基于多参构造方法--> <!-- 步骤1:将对象存放在Ioc容器中--> <bean id="userDao" class="com.alphamilk.loc2.UserDao"/> <bean id="service" class="com.alphamilk.loc2.UserService"> <!-- 方案1:通过使用name对应参数配置【推荐】--> <constructor-arg name="age" value="29"/> <constructor-arg name="name" value="黄小龙"/> <constructor-arg name="userDao" ref="userDao"/> </bean> <bean id="userDao" class="com.alphamilk.loc2.UserDao"/> <bean id="service" class="com.alphamilk.loc2.UserService"> <!-- 方案2:通过顺序的方式传递参数--> <constructor-arg value="黄小龙"/> <constructor-arg value="29"/> <constructor-arg ref="userDao"/> </bean> <bean id="userDao" class="com.alphamilk.loc2.UserDao"/> <bean id="service" class="com.alphamilk.loc2.UserService"> <!-- 方案3:通过下角标位置的方式传递参数--> <constructor-arg index="0" value="黄小龙"/> <constructor-arg index="1" value="29"/> <constructor-arg index="2" ref="userDao"/> </bean>
2.基于setter函数实现对象
基于构造函数的 DI 是通过容器调用具有多个参数的构造函数来完成的,每个参数表示一个依赖项
下面的示例演示通过构造函数注入多个参数,参数包含其他 bean和基本数据类型!
类对象案例:
package com.alphamilk.loc3; public class UserDao { } //setter方式注入 public class UserService { private UserDao userDao = new UserDao(); private String name; private int age; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } }
对应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"> <!--触发 setter方法进行注入--> <bean id="userDao" class="com.alphamilk.loc3.UserDao"/> <!-- name-》属性名 setter方法的 去掉set并且首字母小写的值! 调用set方法名 比如setName -》name value | ref 进行二选一 value=直接属性值 ref = 其他bean的id --> <bean id="service" class="com.alphamilk.loc3.UserService"> <property name="age" value="52"/> <property name="name" value="张三"/> <property name="userDao" ref="userDao"/> </bean> </beans>
编辑
三.创建IoC容器并获取组件
1.创建Ioc容器对象
首先类对象
package com.alphamilk.loc4; public class HelloTemp { public void doWork(){ System.out.println("HelloTemp is Working"); } }
然后进行xml文件配置IoC
<?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="helloTemp" class="com.alphamilk.loc4.HelloTemp"/> </beans>
两种实现创建IoC容器对象
package com.alphamilk.Ioc; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { // 创建SpringIoc容器方法 /* 两个接口 BeanFactory ApplicationContext 四个实现类 ClassPathXmlApplicationContext 读取类路径下的xml配置方式 WebApplicationContext读取指定文件的xml配置方式 FileSystemXmlApplicationContext读取配置类方式的ioc容器 AnnotationApplicationContext web项目专属的配置ioc容器 */ @org.junit.jupiter.api.Test public void createIoc(){ // 方式一:通过直接创建容器并且指定配置文件即可 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Springioc.xml"); // 方式二:通过先创建ioc容器对象,再指定配置文件,再刷新 ClassPathXmlApplicationContext applicationContext1 = new ClassPathXmlApplicationContext(); applicationContext1.setConfigLocations("Springioc.xml"); applicationContext1.refresh(); } }
2.通过创建的容器获取组件
获取组件步骤:1.创建ioc容器 2.获取组件
三种获取组件方式:
- 第一种获取bean的方式,通过获取getBean加上bean的id,返回Object类型,再将其转为对应的类型。
- 第二种获取bean的方式,通过获取bean的同时,指定其返回的类型。
- 第三种获取bean方式,根据类型获取。
package com.alphamilk.Ioc; import com.alphamilk.loc4.HelloTemp; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { @org.junit.jupiter.api.Test public void useBean(){ // 第一种获取bean的方式,通过获取getBean加上bean的id,返回Object类型,再将其转为对应的类型 // 创建Ioc容器 ApplicationContext context = new ClassPathXmlApplicationContext("springioc.xml"); // 获取组件 HelloTemp helloTemp = (HelloTemp) context.getBean("helloTemp"); // 第二种获取bean的方式,通过获取bean的同时,指定其返回的类型 // TODO:注意可能会出现向下转型异常 // 创建Ioc容器 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(); applicationContext.setConfigLocation("springioc.xml"); applicationContext.refresh(); // 获取组件 applicationContext.getBean("helloTemp",HelloTemp.class); // 第三种获取bean方式,根据类型获取 // 创建Ioc容器 ClassPathXmlApplicationContext classPathXmlApplicationContext2 = new ClassPathXmlApplicationContext(); classPathXmlApplicationContext2.setConfigLocation("springioc.xml"); classPathXmlApplicationContext2.refresh(); // 获取组件 // TODO:注意这种方法有许多条件 // 根据bean类型获取,一次只能有一种类型,举例在ioc容器中如果有多个HelloTemp对象,继续使用这种方法会报错 classPathXmlApplicationContext2.getBean(HelloTemp.class); // 注意虽然是三种不同的获取方式,但是获取到的对象都是同一个,三种方法只是对应三种类型的指针指向Ioc容器中存放的组件 helloTemp.doWork(); } }
编辑
深入了解Bean组件