IoC简介
什么是Bean?
Spring Bean是被实例的,组装的及被Spring 容器管理的java对象。
工厂模式发展史
IoC
IoC(Inversion Of Control)控制反转,Spring反向控制应用程序所需要使用的外部资源。
Spring控制的资源全部放置在Spring容器中,该容器称为IoC容器。
IOC入门案例
- 导入spring坐标(5.1.9.release)
- 编写业务层与表现层(模拟)接口与实现类
- 建立spring配置文件
- 配置所需资源(Service)为spring控制的资源
- 表现层(App)通过spring获取资源(Service实例)
IoC入门案例制作步骤-1(坐标依赖)
pom文件:引入Spring坐标依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
</dependencies>
IoC入门案例制作步骤-2(Service层)
定义一个业务接口方法并实现
//接口方法
public interface UserService {
//业务方法
void save();
}
//实现类
public class UserServiceImpl implements UserService{
//业务方法实现
public void save(){
System.out.println("user service running...");
}
}
IoC入门案例制作步骤-3(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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 1.创建spring控制的资源-->
<bean id="userService" class="com.xxxx.service.impl.UserServiceImpl" />
</beans>
IoC入门案例制作步骤-4(controller层)
public static void main(String[] args) {
//2.加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//3.获取资源
UserService userService = (UserService) ctx.getBean("userService");
userService.save();
}
小节
入门案例步骤
- 导入Spring坐标
- 编写Service层
- xml配置文件创建Bean
- controller层通过读取配置文件,获取Service对象并执行方法
IoC配置(XML格式)
- Bean标签:定义spring中的资源,受此标签定义的资源将受到spring控制
- Bean标签id,class,name属性
- Bean标签scope,init-method,destroy-method属性
<bean id="beanId"
name="beanName1,beanName2"
class="ClassName"
scope="singleton"
init-method="init" destroy-method="destroy></bean>
◆ id:bean的名称,通过id值获取bean
◆ class:bean的类型
◆ name:bean的名称,可以通过name值获取bean
◆scope:
◆ singleton:设定创建出的对象保存在spring容器中,是一个单例的对象
◆ prototype:设定创建出的对象保存在spring容器中,是一个非单例的对象
◆ request、session、application、 websocket :设定创建出的对象放置在web容器对应的位置
◆init-method,destroy-method 取值:bean对应的类中对应的具体方法名
◆ 当scope=“singleton”时,初始化spring容器时创建Bean对象
◆ 当scope=“prototype”时,获取对象时创建对象
时均执行一次
◆ 当scope=“singleton”时,关闭容器会导致bean实例的销毁,调用destroy方法一次
◆ 当scope=“prototype”时,对象的销毁由垃圾回收机制gc()控制,destroy方法将不会被执行
Bean标签属性小节
- bean
- id
- class
- scope
- name
- init-method
- destroy-method
创建bean对象方式(三种)
- 静态工厂的形式创建bean
- 实例工厂的形式创建bean
- 构造方法的形式创建bean
静态工厂创建bean
package com.xxxx.service;
import com.xxxx.service.impl.UserServiceImpl;
//静态工厂
public class UserServiceFactory {
public static UserService getService(){
System.out.println("factory create object...");
return new UserServiceImpl();
}
}
----xml配置文件
//Bean标签创建Spring控制的资源
<!--静态工厂创建bean-->
<bean
id="userService4"
class="com.xxxx.service.UserServiceFactory"
factory-method="getService"/>
实例工厂创建bean
package com.xxxx.service;
import com.xxxx.service.impl.UserServiceImpl;
public class UserServiceFactory2 {
public UserService getService(){
System.out.println(" instance factory create object...");
return new UserServiceImpl();
}
}
----xml配置文件
<!-- 先创建实例工厂的bean-->
<bean
id="factoryBean"
class="com.xxxx.service.UserServiceFactory2"/>
<!--实例工厂创建bean,在创建依赖工厂的对象对应的bean-->
<bean id="userService5"
factory-bean="factoryBean"
factory-method="getService" />
构造方法创建bean(必须要有无参构造方法)
package com.xxxx.service.impl;
import com.xxxx.service.UserService;
public class UserServiceImpl implements UserService {
// 无参构造方法
public UserServiceImpl(){
System.out.println(" constructor is running...");
}
public void save() {
System.out.println("user service running...");
}
}
---xml配置:
bean id="userService" name="userService1,userService2" class="com.xxxx.service.impl.UserServiceImpl"/>
DI(Dependency Injection)依赖注入
- 应用程序运行依赖的资源由Spring为其提供,资源进入应用程序的方式称为注入。
依赖注入的三种方式
- set注入(常用)
- 构造器(构造方法)注入
- 集合类型数据注入
set注入(通过set方法)
package com.xxxx.service.impl;
import com.xxxx.dao.BookDao;
import com.xxxx.dao.UserDao;
import com.xxxx.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao;
private BookDao bookDao;
private int num;
private String version;
//1.对需要进行set注入的变量添加set方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void setVersion(String version) {
this.version = version;
}
public void setNum(int num) {
this.num = num;
}
//无参构造方法用于创建( UserServiceImpl)Bean
public UserServiceImpl() {
}
public UserServiceImpl(UserDao userDao, int num, String version){
this.userDao = userDao;
this.num = num;
this.version = version;
}
public void save() {
System.out.println("user service running..."+num+" "+version);
userDao.save();
bookDao.save();
}
}
---xml配置文件:
<!--2.将要注入的资源声明为bean-->
<bean id="userDao" class="com.xxxx.dao.impl.UserDaoImpl"> </bean>
<!-- set注入实验 -->
<bean id="userService" class="com.xxxx.service.impl.UserServiceImpl">
<!--3.将要注入的引用类型的变量通过property属性进行注入,对应的name是要注入的变量名,使用ref属性声明要注入的bean的id-->
<property name="userDao" ref="userDao"/>
<property name="num" value="666"/>
<property name="version" value="beijing"/>
</bean>
set注入小结
◆ 对应的set方法
◆ bean中使用property标签注入属性
◆ name :注入的属性名
◆ 对象类型:使用ref进行注入
◆ 其他:使用value进行注入
构造器注入(通过有参构造方法)
package com.xxxx.service.impl;
import com.xxxx.dao.BookDao;
import com.xxxx.dao.UserDao;
import com.xxxx.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao;
private BookDao bookDao;
private int num;
private String version;
//1.对需要进行set注入的变量添加set方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void setVersion(String version) {
this.version = version;
}
public void setNum(int num) {
this.num = num;
}
//无参构造方法用于创建( UserServiceImpl)Bean
public UserServiceImpl() {
}
//2.对需要进行构造注入的变量创建有参构造方法
public UserServiceImpl(UserDao userDao, int num, String version){
this.userDao = userDao;
this.num = num;
this.version = version;
}
public void save() {
System.out.println("user service running..."+num+" "+version);
userDao.save();
bookDao.save();
}
}
---xml配置文件
<!--2.将要注入的资源声明为bean-->
<bean id="userDao" class="com.xxxx.dao.impl.UserDaoImpl"> </bean>
<!-- 构造器注入实验 -->
<bean id="userDao" class="com.xxxx.dao.impl.UserDaoImpl">
<constructor-arg index="2" value="123"/>
<constructor-arg index="1" value="root"/>
<constructor-arg index="0" value="com.mysql.jdbc.Driver"/>
</bean>
<!-- 构造器注入顺序实验 -->
<bean id="userService" class="com.xxxx.service.impl.UserServiceImpl">
<!--使用构造方法进行set注入,需要保障注入的属性与bean中定义的属性一致-->
<!--一致指顺序一致或类型一致或使用index解决该问题-->
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="num" value="666666"/>
<constructor-arg name="version" value="itcast"/>
</bean>
构造方法注入小节
◆ 有参构造方法
◆ bean中使用 constructor-arg标签注入属性
◆ name表示注入的属性名
◆ 对象:使用ref进行注入
◆ 其他:使用value进行注入
◆ 支持按类型注入
◆ 支持按顺序注入
集合类型数据注入(通过构造方法)
数据类型:array,list,set,map,props
package com.xxxx.dao.impl;
import com.xxxx.dao.BookDao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
public class BookDaoImpl implements BookDao {
private ArrayList al;
private Properties properties;
private int[] arr;
private HashSet hs;
private HashMap hm ;
public void setAl(ArrayList al) {
this.al = al;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void setArr(int[] arr) {
this.arr = arr;
}
public void setHs(HashSet hs) {
this.hs = hs;
}
public void setHm(HashMap hm) {
this.hm = hm;
}
public void save() {
System.out.println("book dao running...");
System.out.println("ArrayList:"+al);
System.out.println("Properties:"+properties);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("HashSet:"+hs);
System.out.println("HashMap:"+hm);
}
}
xml配置文件
<!-- 集合注入顺序实验 -->
<bean id="bookDao" class="com.xxxx.dao.impl.BookDaoImpl">
<property name="al">
<list>
<value>beijing</value>
<value>66666</value>
</list>
</property>
<property name="properties">
<props>
<prop key="name">123666</prop>
<prop key="value">666666</prop>
</props>
</property>
<property name="arr">
<array>
<value>123456</value>
<value>66666</value>
</array>
</property>
<property name="hs">
<set>
<value>qqqqq</value>
<value>66666</value>
</set>
</property>
<property name="hm">
<map>
<entry key="name" value="itheima66666"/>
<entry key="value" value="6666666666"/>
</map>
</property>
</bean>
使用p命名空间简化配置