IOC
概念
IOC (Inverse of Control)即控制反转:由ioc容器来创建依赖对象,程序只需要从IOC容器获取创建好的对象。
- 原来:
我们在获取对象时,都是采用new的方式。是主动的。
- 现在:
我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
这种被动接收的方式获取对象的思想就是控制反转,它是spring框架的核心之一。
例子
1. pom.xml
java
<dependencies>
<!-- Spring常用依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
</dependencies>
2.DAO
java
/**
* 持久层实现类
*/
public class UserDaoImpl implements UserDao {
@Override
public void addUser(){
System.out.println("insert into tb_user......");
}
}
3.Service
java
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
//此处有依赖关系
private UserDao userDao = new UserDaoImpl();
public void addUser(){
userDao.addUser();
}
}
4.applicationContext.xml
java
<?xml version="1.0" encoding="UTF-8"?>
<!--1、注意:要导入schema约束-->
<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">
<!--
2、把对象交给spring来创建
id:给对象在容器中提供一个唯一标识。用于获取对象
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数
-->
<bean id="userDao" class="com.by.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.by.service.UserServiceImpl"></bean>
</beans>
5.测试
java
/**
* 模拟表现层
*/
public class Client {
public static void main(String[] args) {
//1.使用ApplicationContext接口,就是在获取spring容器
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext.xml");
//2.根据bean的id获取对象
UserDao userDao = (UserDao) ac.getBean("userDao");
System.out.println(userDao);
UserService userService = (UserService) ac.getBean("userService");
System.out.println(userService);
userService.addUser();
}
}
applicationContext.xml注意的细节
- 只配置class属性
java
<bean class="com.by.pojo.User"/>
a) 上述这种配置 有没有id值 com.by.pojo.User#0
b) 应⽤场景:
-
如果这个bean只需要使⽤⼀次,那么就可以省略id值
-
如果这个bean会使⽤多次,或者被其他bean引⽤则需要设置id值
-
name属性
作⽤:⽤于在Spring的配置⽂件中,为bean对象定义别名(⼩名)
相同:
ctx.getBean("id|name")-->object
<bean id="" class=""
等效
<bean name="" class=""
区别:
- 别名可以定义多个,但是id属性只能有⼀个值
- XML的id属性的值,命名要求:必须以字⺟开头,字⺟ 数字 下划线 连字符 不
能以特殊字符开头 /person
name属性的值,命名没有要求 /person
name属性会应⽤在特殊命名的场景下
-
class属性
写的是要创建对象的全限定名
-
Spring工厂的相关方法
- Object getBean(String key);
通过这种⽅式获得对象,就不需要强制类型转换
Person person = ctx.getBean("user", User.class);
System.out.println("user = " + user);
- '<'T>T getBean(String key,Class requiredType);
通过这种⽅式获得对象,就不需要强制类型转换
Person person = ctx.getBean("user", User.class);
System.out.println("user = " + user);
- '<'T>T getBean(Class requiredType);
当前Spring的配置⽂件中 只能有⼀个<bean class是Person类型
Person person = ctx.getBean(Person.class);
System.out.println("person = " + person);
- String[] getBeanDefinitionNames()
获取的是 Spring⼯⼚配置⽂件中所有bean标签的id值 person person1
String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName = " +beanDefinitionName);
}
- String[] getBeanNamesForType(Class requiredType);
根据类型获得Spring配置⽂件中对应的id值
String[] beanNamesForType = ctx.getBeanNamesForType(Person.class);
for (String id : beanNamesForType) {
System.out.println("id = " + id);
}
- boolean containsBeanDefinition(string key);
⽤于判断是否存在指定id值得bean
if (ctx.containsBeanDefinition("a")) {
System.out.println("true = " + true);
}else{
System.out.println("false = " + false);
}
- boolean containsBean(String key);
⽤于判断是否存在指定id值得bean
if (ctx.containsBean("person")) {
System.out.println("true = " + true);
}else{
System.out.println("false = " + false);
}
- Object getBean(String key);