一、IOC基本概念--2W1H
1.1 什么是控制反转(WHAT)
控制:谁创建和管理对象
反转:程序不创建和管理对象,而变成接收对象
//传统对象创建方式:User user=new User();
public class TestCommon {
public static void main(String[] args) {
User user=new User();
user.setAge(15);
System.out.println(user);
}
}
/**
* 使用spring后,对象由spring工厂创建,
* 程序使用context.getBean("user")接收对象
*/
public class TestSpring {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
User user = (User) context.getBean("user");
user.setAge(15);
System.out.println(user);
}
}
1.2 为什么使用IOC(WHY)
解耦(工厂设计模式的作用为解耦)
1.3 如何实现(HOW,底层原理)
简单工厂模式+配置文件+反射
1.3.1 自定义BeanFactory【简单模拟spring提供的BeanFactory,见1.3.2】
第一步:定义配置文件
为了演示方便,我们使用properties文件作为配置文件,名称为bean.properties
american=com.itheima.pattern.factory.config_factory.AmericanCoffee latte=com.itheima.pattern.factory.config_factory.LatteCoffee
第二步:简单工厂+反射
public class MyBeanFactory{
//定义容器,用以存储对象
private static Map<String,Object> map = new HashMap();
//定义静态代码块,用以类加载时就执行,且仅执行一次。
static {
//读取配置文件
Properties p = new Properties();
InputStream is = MyBeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
p.load(is);
//遍历Properties集合对象
Set<Object> keys = p.keySet();
for (Object key : keys) {
//根据键获取值(全类名)
String className = p.getProperty((String) key);
//获取字节码对象
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();
map.put((String)key,obj);//加载时创建配置文件中指定的所有对象
}
} catch (Exception e) {
e.printStackTrace();
}
}
//提供外部获取bean方法
public static Object getBean(String name) {
return map.get(name);
}
1.3.2 spring提供的2个BeanFactory
(1)面向Web应用的bean工厂:XmlWebApplicationContext【对应注解版的AnnotationConfigWebApplicationContext】
(2)面向非Web应用的bean工厂:ClassPathXmlApplicationContext【对应注解版的AnnotationConfigApplicationContext】
1.3.3 BeanFactory与ApplicationContext的关系
(摘自《Spring 3.0就这么简单》--陈雄华,林开雄)
继承关系如下图
1.3.4 BeanFactory与FactoryBean的关系
BeanFactory与FactoryBean,两个名字很像,容易搞混,所以在此笔记区分:
(1)BeanFactory: 以Factory结尾,表示它是一个工厂类,是用于管理Bean的一个工厂:它对于Bean的创建有一个统一的流程。
(2)FactoryBean: 以Bean结尾,表示它是一个工厂Bean,它最大的一个作用是:可以让我们自定义Bean的创建过程。常用来创建复杂对象。
不同于普通Bean的是:根据该Bean的id从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身, 如果要获取FactoryBean对象本身,可以在id前面加一个&符号来获取。(参考:spring--IOC--02--Bean对象创建--01--XML版--复杂对象创建)
参考:spring关于FactoryBean的基本介绍_CAUC_lin的博客-CSDN博客
二、Spring IOC学习包含内容
2.1 bean创建【注册组件】
2.2 bean生命周期
2.3 属性赋值