1. 什么是IOC/DI
1.IOC:控制反转,将 bean的对象交给 spring容器来管理。
2.DI:依赖注入,解决对象之间的依赖关系。
2. Spring容器,就是Spring帮忙管理类(JavaBean),我们先写一个简单的单例容器,Bean的配置写在配置文件(applicationContext.properties)中,要根据名字获取一个bean,就需要用到工厂,当工厂被实例化时,就会用资源加载器,去反射创建bean(也就是beanDefinition),然后存入beanDefinitionMap。
beanDefinition不是一个普通的类,而是一个有beanName和ClassName的类,有了这两项才好被用来创建(反射)和管理(配合注册机)bean的使用实例。
package clz.spring.ioc;
public class User {
private String userId;
private String name;
public User() {
}
public User(String userId, String name) {
super();
this.userId = userId;
this.name = name;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}package clz.spring.ioc;
import java.lang.reflect.Constructor;
public class TestReflection {
public static void main(String[] args) throws Exception {
Class<?> clz = Class.forName("clz.spring.User");
//获取参数为<String,String>的构造器
Constructor<?> constructor = clz.getConstructor(String.class, String.class);
Object object = constructor.newInstance("userId_001","name_jack");
// System.out.println(object instanceof User);
if (object instanceof User) {
User user = (User)object;
System.out.println("userId:" + user.getUserId());
System.out.println("name:" + user.getName());
}
}
}
通过资源加载创建的beanDefinition先放置到beanDefinitionMap(一个临时的bean表),每次getBean(通过beanName)的时候,如果注册机已经注册了这个bean,那么直接从注册机获取,否则从beanDefinitionMap中取出beanDefinition,根据beanDefinition的内容反射创建实例,并通过工厂内部的BeanRegister注册机(本质也是一个HashMap)进行注册。
IOC代码如下
userDao:UserDaopublic class UserDao {
public void queryUserInfo(){
System.out.println("A good man.");
}
}
package clz.spring.ioc;
import java.lang.reflect.Constructor;
public class TestReflection {
public static void main(String[] args) throws Exception {
Class<?> clz = Class.forName("test.java.zxj.test_project.User");
//获取参数为<String,String>的构造器
Constructor<?> constructor = clz.getConstructor(String.class, String.class);
Object object = constructor.newInstance("userId_001","name_jack");
// System.out.println(object instanceof User);
if (object instanceof User) {
User user = (User)object;
System.out.println("userId:" + user.getUserId());
System.out.println("name:" + user.getName());
}
}
}
package clz.spring.ioc;
import java.util.*;
import java.io.*;
public class ResourceLoader {
public static Map<String, BeanDefinition> getResource() {
Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>(16);
Properties properties = new Properties();
try {
InputStream inputStream = ResourceLoader.class.getResourceAsStream("/applicationContext.properties");
properties.load(inputStream);
Iterator<String> it = properties.stringPropertyNames().iterator();
while (it.hasNext()) {
String key = it.next();
String className = properties.getProperty(key);
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setBeanName(key);
Class clazz = Class.forName(className);
beanDefinition.setBeanClass(clazz);
beanDefinitionMap.put(key, beanDefinition);
}
inputStream.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return beanDefinitionMap;
}
}
package clz.spring.ioc;
import java.util.*;
public class BeanRegister {
//单例Bean缓存
private Map<String, Object> singletonMap = new HashMap<>(32);
/**
* 获取单例Bean
*
* @param beanName bean名称
* @return
*/
public Object getSingletonBean(String beanName) {
return singletonMap.get(beanName);
}
/**
* 注册单例bean
*
* @param beanName
* @param bean
*/
public void registerSingletonBean(String beanName, Object bean) {
if (singletonMap.containsKey(beanName)) {
return;
}
singletonMap.put(beanName, bean);
}
}
package clz.spring.ioc;
public class BeanDefinition {
private String beanName;
private Class beanClass;
private boolean isSingleTone=true;
public boolean isSingleTone() {
return isSingleTone;
}
public void setSingleTone(boolean singleTone) {
isSingleTone = singleTone;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public Class getBeanClass() {
return beanClass;
}
public void setBeanClass(Class beanClass) {
this.beanClass = beanClass;
}
}
package clz.spring.ioc;
import java.util.HashMap;
import java.util.Map;
public class BeanFactory {
Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();
BeanRegister beanRegister;
public BeanFactory()
{
beanRegister=new BeanRegister();
this.beanDefinitionMap= ResourceLoader.getResource();
}
//创建bean
public Object createBean(String beanName)
{
//获取bean 定义
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
//通过反射创建bean
try {
Object bean = beanDefinition.getBeanClass().newInstance();
//缓存bean
//如果是单例,则放入beanRegister中
if(beanDefinition.isSingleTone())
{
beanRegister.registerSingletonBean(beanDefinition.getBeanName(), bean);
}
return bean;
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
//获取bean
public Object getBean(String beanName)
{
Object object = beanRegister.getSingletonBean(beanName);
if(object!=null)
{
return object;
}
else {
object = createBean(beanName);
}
return null;
}
}