手撸spring源码分析IOC实现原理

手撸spring源码分析IOC实现原理
文章出处:https://github.com/fuzhengwei/small-spring
根据小付哥的手撸spring核心源码一步步学习出来的结果收货总结。

spring容器Ioc初次体验

BeanDefinition :Object对象。

public class BeanDefinition {

    private Object bean;

    public BeanDefinition(Object bean) {
        this.bean = bean;
    }

    public Object getBean() {
        return bean;
    }

}

beanFactory:容器工厂对象。一个map集合用于存储实例对象。

为什么使用map集合进行存储?
ArrayList、LinkedList、HashSet等,但在 Spring Bean 容器的场景下,
我们需要一种可以用于存放和名称索引式的数据结构,所以选择 HashMap 是最合适不过的。

public class BeanFactory {

    private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    public Object getBean(String name) {
        return beanDefinitionMap.get(name).getBean();
    }

    public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(name, beanDefinition);
    }

}
public class UserService {

    public void queryUserInfo(){
        System.out.println("111");
    }
    public  UserService(){
        System.out.println("默认无参构造创造");
    }
}
@Test
public void test_BeanFactory(){
    // 1.初始化 BeanFactory
    BeanFactory beanFactory = new BeanFactory();
    
    // 2.注册 bean
    BeanDefinition beanDefinition = new BeanDefinition(new UserService());
    beanFactory.registerBeanDefinition("userService", beanDefinition);
    
    // 3.获取 bean
    UserService userService = (UserService) beanFactory.getBean("userService");
    userService.queryUserInfo();
}

spring初显身手,运用设计模式,实现 Bean 的定义、注册、获取

本章将 Spring Bean 容器完善起来,首先非常重要的一点是在 Bean 注册的时候只注册一个类信息,而不会直接把实例化信息注册到 Spring 容器中。那么就需要修改 BeanDefinition 中的属性 Object 为 Class,接下来在需要做的就是在获取 Bean 对象时需要处理 Bean 对象的实例化操作以及判断当前单例对象在容器中是否已经缓存起来了
在这里插入图片描述

BeanDefinition 定义

public class BeanDefinition {

    private Class beanClass;

    public BeanDefinition(Class beanClass) {
        this.beanClass = beanClass;
    }
    // ...get/set
}

单例注册接口定义和实现

//获取单例对象的接口
public interface SingletonBeanRegistry {

    Object getSingleton(String beanName);

}
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {

    private Map<String, Object> singletonObjects = new HashMap<>();

    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }

    protected void addSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName, singletonObject);
    }

}
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    @Override
    public Object getBean(String name) throws BeansException {
        Object bean = getSingleton(name);
        if (bean != null) {
            return bean;
        }

        BeanDefinition beanDefinition = getBeanDefinition(name);
        return createBean(name, beanDefinition);
    }

    protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;

    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException;

}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {

    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {
        Object bean = null;
        try {
            bean = beanDefinition.getBeanClass().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new BeansException("Instantiation of bean failed", e);
        }

        addSingleton(beanName, bean);
        return bean;
    }

}
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {

    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }

    @Override
    public BeanDefinition getBeanDefinition(String beanName) throws BeansException {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) throw new BeansException("No bean named '" + beanName + "' is defined");
        return beanDefinition;
    }

}
@Test
public void test_BeanFactory(){
    // 1.初始化 BeanFactory
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    // 2.注册 bean
    BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
    beanFactory.registerBeanDefinition("userService", beanDefinition);
    // 3.第一次获取 bean
    UserService userService = (UserService) beanFactory.getBean("userService");
    userService.queryUserInfo();
    // 4.第二次获取 bean from Singleton
    UserService userService_singleton = (UserService) beanFactory.getBean("userService");
    userService_singleton.queryUserInfo();
}

执行流程分析

实例化一个容器
在这里插入图片描述

需要实例化对象的class,然后注册到容器中

在这里插入图片描述

在这里插入图片描述

注意:默认调用无参构造进行创建,如果重新了有参构造后会实例失败。

基于Cglib实现含构造函数的类实例化策略

public interface BeanFactory {

    Object getBean(String name) throws BeansException;

    Object getBean(String name, Object... args) throws BeansException;

}
public interface InstantiationStrategy {

    Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException;

}

基于jdk的实例化

public class SimpleInstantiationStrategy implements InstantiationStrategy {

    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        Class clazz = beanDefinition.getBeanClass();
        try {
            if (null != ctor) {
                return clazz.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
            } else {
                return clazz.getDeclaredConstructor().newInstance();
            }
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new BeansException("Failed to instantiate [" + clazz.getName() + "]", e);
        }
    }

}

基于Cglib的实例化

public class CglibSubclassingInstantiationStrategy implements InstantiationStrategy {

    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(beanDefinition.getBeanClass());
        enhancer.setCallback(new NoOp() {
            @Override
            public int hashCode() {
                return super.hashCode();
            }
        });
        if (null == ctor) return enhancer.create();
        return enhancer.create(ctor.getParameterTypes(), args);
    }

}

如果实例的:采用cglib

在这里插入图片描述

对象属性值填充

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eTfl85V2-1637294071811)(C:\Users\CDIT005\AppData\Roaming\Typora\typora-user-images\image-20211013144453357.png)]

从Spring.xml解析和注册Bean对象

优化从配置文件中实例化bean

在这里插入图片描述

step1:实例化beanFactory。
step2:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
会判断当前传入的location是属于哪些类型的,classpathResource还是fileSystemResource还是Url 判断方式如下图
在这里插入图片描述
在这里插入图片描述

根据返回的Resource转为输入流,在这里插入图片描述

把当前输入流转为xml对象进行读取属性赋值操作后 放入到DefaultListableBeanFactory中的private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>()中去。此时DefaultListableBeanFactory中的map中已经保存了bean的定义信息,在去进行实例化,从而完成冲配置文件中实例化bean。

step3:如何实例化:

在这里插入图片描述

先冲缓存中根据key(bean的name名称)取,如果没有则创建后添加到缓存中并返回,如果有直接返回。

实现应用上下文,自动识别、资源加载、扩展机制

BeanFactoryPostProcessor(bean的定义信息加载之后,bean实例化之前执行改接口实现方法,用于BeanDefinition的修改)

BeanPostProcessor(实例化前的提前处理:准确来说是提前于bean实例化,利用在实例化之前检查是否存在合适的BeanPostProcessor对象,去拦截某些需要被处理的bean提前完成bean的实例化过程,不会去调用init方法,也没有数据的填充)

流程分析图:

准备实体:

public class UserService {

    private String uId;
    private String company;
    private String location;
    private UserDao userDao;
    //setter and  getter
}

MyBeanFactoryPostProcessor:用于测试BeanFactoryPostProcessor

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
        PropertyValues propertyValues = beanDefinition.getPropertyValues();

        propertyValues.addPropertyValue(new PropertyValue("company", "改为:字节跳动"));
    }

}

MyBeanPostProcessor:用于测试BeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName)) {
            UserService userService = (UserService) bean;
            userService.setLocation("改为:北京");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

}

准备就绪开干:

测试方法:

@Test
public void test_xml() {
    // 1.初始化 BeanFactory
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:springPostProcessor.xml");

    // 2. 获取Bean对象调用方法
    UserService userService = applicationContext.getBean("userService", UserService.class);
    String result = userService.queryUserInfo();
    System.out.println("测试结果:" + result);
}

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(“classpath:springPostProcessor.xml”)

  1. 装载所有的Bean对象。
  2. 具体流程如下图所示
    在这里插入图片描述

**核心方法:refresh()在这里插入图片描述

refreshBeanFactory();方法(作用: 创建 BeanFactory,并加载 BeanDefinition)

在这里插入图片描述

  1. 在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {

    public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
        super(registry);
    }

    public XmlBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) {
        super(registry, resourceLoader);
    }

    @Override
    public void loadBeanDefinitions(Resource resource) throws BeansException {
        try {
            try (InputStream inputStream = resource.getInputStream()) {
                doLoadBeanDefinitions(inputStream);
            }
        } catch (IOException | ClassNotFoundException e) {
            throw new BeansException("IOException parsing XML document from " + resource, e);
        }
    }

    @Override
    public void loadBeanDefinitions(Resource... resources) throws BeansException {
        for (Resource resource : resources) {
            loadBeanDefinitions(resource);
        }
    }

    @Override
    public void loadBeanDefinitions(String location) throws BeansException {
        ResourceLoader resourceLoader = getResourceLoader();
        Resource resource = resourceLoader.getResource(location);
        loadBeanDefinitions(resource);
    }

    @Override
    public void loadBeanDefinitions(String... locations) throws BeansException {
        for (String location : locations) {
            loadBeanDefinitions(location);
        }
    }

    protected void doLoadBeanDefinitions(InputStream inputStream) throws ClassNotFoundException {
        Document doc = XmlUtil.readXML(inputStream);
        Element root = doc.getDocumentElement();
        NodeList childNodes = root.getChildNodes();

        for (int i = 0; i < childNodes.getLength(); i++) {
            // 判断元素
            if (!(childNodes.item(i) instanceof Element)) continue;
            // 判断对象
            if (!"bean".equals(childNodes.item(i).getNodeName())) continue;

            // 解析标签
            Element bean = (Element) childNodes.item(i);
            String id = bean.getAttribute("id");
            String name = bean.getAttribute("name");
            String className = bean.getAttribute("class");
            // 获取 Class,方便获取类中的名称
            Class<?> clazz = Class.forName(className);
            // 优先级 id > name
            String beanName = StrUtil.isNotEmpty(id) ? id : name;
            if (StrUtil.isEmpty(beanName)) {
                beanName = StrUtil.lowerFirst(clazz.getSimpleName());
            }

            // 定义Bean
            BeanDefinition beanDefinition = new BeanDefinition(clazz);
            // 读取属性并填充
            for (int j = 0; j < bean.getChildNodes().getLength(); j++) {
                if (!(bean.getChildNodes().item(j) instanceof Element)) continue;
                if (!"property".equals(bean.getChildNodes().item(j).getNodeName())) continue;
                // 解析标签:property
                Element property = (Element) bean.getChildNodes().item(j);
                String attrName = property.getAttribute("name");
                String attrValue = property.getAttribute("value");
                String attrRef = property.getAttribute("ref");
                // 获取属性值:引入对象、值对象
                Object value = StrUtil.isNotEmpty(attrRef) ? new BeanReference(attrRef) : attrValue;
                // 创建属性信息
                PropertyValue propertyValue = new PropertyValue(attrName, value);
                beanDefinition.getPropertyValues().addPropertyValue(propertyValue);
            }
            if (getRegistry().containsBeanDefinition(beanName)) {
                throw new BeansException("Duplicate beanName[" + beanName + "] is not allowed");
            }
            // 注册 BeanDefinition
            getRegistry().registerBeanDefinition(beanName, beanDefinition);
        }
    }

}

在这里插入图片描述

注册 BeanDefinition: getRegistry().registerBeanDefinition(beanName, beanDefinition);

在这里插入图片描述

在这里插入图片描述

以上操作完成bean的加载和注册


ConfigurableListableBeanFactory beanFactory = getBeanFactory();

在这里插入图片描述
在这里插入图片描述

invokeBeanFactoryPostProcessors(beanFactory);

在这里插入图片描述

在这里插入图片描述

registerBeanPostProcessors(beanFactory);

在这里插入图片描述
在这里插入图片描述

上图只是拿到了banFactory中有哪些是BeanPostProcessor的子类。并不会立即处理。

beanFactory.preInstantiateSingletons(); 实例化对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到此完成了BeanDefinition的的修改。完成了BeanPostProcessor和BeanFactoryPostProcessor的对bean的不同时机的修改操作!

1.整体流程说明:根据传入的路径。判断出具体的解析方式是classpath,url,FileSystem。然后读取配置中的Bean定义信息。完成对BeanDefinition第一次的初始化操作并放入DefaultListableBeanFactory中的beanDefinitionMap中去。

2.获取到DefaultListableBeanFactory对象。(这个对象包含bean的定义信息)

3.执行BeanFactoryPostProcessor。说白了就拿到实现了BeanFactoryPostProcessor接口的类,然后拿到需要修改的属性。放入List propertyValueList = new ArrayList<>();集合中去。

4,在实例化bean之前提前拿到实现了BeanPostProcessor的类。然后放入AbstractBeanFactory 中的List beanPostProcessors = new ArrayList();集合中去。

5.创建实例:实例化对象(cglib或jdk),给 Bean 填充属性时执行List propertyValueList = new ArrayList<>();循环然后覆盖。执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法。

龙行有风,向虚拟机注册钩子,实现Bean对象的初始化和销毁方法

定义初始化和销毁方法的接口(init-method、destroy-method)加入bean的生命周期

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Aware接口作用。

让所有继承Aware接口的接口都具有感知功能。

在这里插入图片描述

让所有实现Aware接口的接口的类都能获取对应的属性。

这个在实例化和初始化bean对象之后,bean = initializeBean(beanName, bean, beanDefinition);方法时执行

    protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
        Object bean = null;
        try {
            bean = createBeanInstance(beanDefinition, beanName, args);
            // 给 Bean 填充属性
            applyPropertyValues(beanName, bean, beanDefinition);
            // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法
            bean = initializeBean(beanName, bean, beanDefinition);
        } catch (Exception e) {
            throw new BeansException("Instantiation of bean failed", e);
        }

        // 注册实现了 DisposableBean 接口的 Bean 对象
        registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);

        // 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE
        if (beanDefinition.isSingleton()) {
            registerSingleton(beanName, bean);
        }
        return bean;
    }

判断你当前的这个bean对象有没有实现对应的Aware接口,如果实现了,调用对应xxxAware接口的方法,给你塞对应的参数。然后执行一些初始化方法以及前后处理逻辑

        // invokeAwareMethods 判断当前bean对象有没有实现各种Aware接口
        if (bean instanceof Aware) {
        //实现了BeanFactoryAware就调用BeanFactoryAware的setBeanFactory方法。
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(this);
            }
            if (bean instanceof BeanClassLoaderAware) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
            }
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
        }
        // 1. 执行实现了InitializingBean的方法前执行BeanPostProcessor Before 处理
        Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);

        // 执行 Bean 对象的初始化方法
        try {
            //2. 执行实现了InitializingBean接口的bean。 invokeInitMethods(beanName, wrappedBean, beanDefinition);
        } catch (Exception e) {
            throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e);
        }

        // 3. 执行实现了InitializingBean的方法后执行执行 BeanPostProcessor After 处理
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        return wrappedBean;
    }

spring事件处理方法

    public void refresh() throws BeansException {
        // 6. 初始化事件发布者
        initApplicationEventMulticaster();

        // 7. 注册事件监听器
        registerListeners();

        // 9. 发布容器刷新完成事件
        finishRefresh();
    }
    6.1//这个方法就实例化一个SimpleApplicationEventMulticaster对象出来,然后注册进beanFactory工厂中
        private void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //这个方法就实例化一个SimpleApplicationEventMulticaster对象出来,然后
        applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        //注册进beanFactory工厂中
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, applicationEventMulticaster);
    }
    7.1 判断容器内的bean对象,哪些实现了ApplicationListener接口的bean,
        全部拿出来,然后放入一个事件监听集合applicationListeners中
        private void registerListeners() {
        //实现了ApplicationListener接口的bean
        Collection<ApplicationListener> applicationListeners = getBeansOfType(ApplicationListener.class).values();
        for (ApplicationListener listener : applicationListeners) {
        //放入事件监听集合中
            applicationEventMulticaster.addApplicationListener(listener);
        }
    }
    // 9.1 比如:发布容器刷新完成事件
    //发布的事件对象时ContextRefreshedEvent
    publishEvent(new ContextRefreshedEvent(this));
   
   //调用事件发布
    public void publishEvent(ApplicationEvent event) {
    applicationEventMulticaster.multicastEvent(event);
}
//获取对应的事件监听对象getApplicationListeners(event)方法,然后发布事件
    public void multicastEvent(final ApplicationEvent event) {
        for (final ApplicationListener listener : getApplicationListeners(event)) {
        //发布事件
            listener.onApplicationEvent(event);
        }
    }
    //拿到所以的监听事件applicationListeners集合,
    //然后判断当前事件和集合中哪些监听事件的类型一致的。supportsEvent(listener, event),就添加到另一个集合中返回出去,然后发布事件
   protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) {
   LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
   for (ApplicationListener<ApplicationEvent> listener : applicationListeners) {
       if (supportsEvent(listener, event)) allListeners.add(listener);
   }
   return allListeners;
}

    /**
     * 监听器是否对该事件感兴趣
     */
    protected boolean supportsEvent(ApplicationListener<ApplicationEvent> applicationListener, ApplicationEvent event) {
        Class<? extends ApplicationListener> listenerClass = applicationListener.getClass();

        // 按照 CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy 不同的实例化类型,需要判断后获取目标 class
        Class<?> targetClass = ClassUtils.isCglibProxyClass(listenerClass) ? listenerClass.getSuperclass() : listenerClass;
        Type genericInterface = targetClass.getGenericInterfaces()[0];

        Type actualTypeArgument = ((ParameterizedType) genericInterface).getActualTypeArguments()[0];
        String className = actualTypeArgument.getTypeName();
        Class<?> eventClassName;
        try {
            eventClassName = Class.forName(className);
        } catch (ClassNotFoundException e) {
            throw new BeansException("wrong event class name: " + className);
        }
        // 判定此 eventClassName 对象所表示的类或接口与指定的 event.getClass() 参数所表示的类或接口是否相同,或是否是其超类或超接口。
        // isAssignableFrom是用来判断子类和父类的关系的,或者接口的实现类和接口的关系的,默认所有的类的终极父类都是Object。如果A.isAssignableFrom(B)结果是true,证明B可以转换成为A,也就是A可以由B转换而来。
        return eventClassName.isAssignableFrom(event.getClass());
    }

spring三级缓存解决循环依赖问题(暂未看完)

A 创建时需要依赖 B 创建,而B 的创建又依赖于 A 创建,就这样死循环了

分类:

在这里插入图片描述


一级缓存解决方式:

package cn.bugstack.springframework.test;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CircleTest {

    private final static Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    public static void main(String[] args) throws Exception {
        System.out.println(getBean(B.class).getA());
        System.out.println(getBean(A.class).getB());
    }

    private static <T> T getBean(Class<T> beanClass) throws Exception {
        String beanName = beanClass.getSimpleName().toLowerCase();
        if (singletonObjects.containsKey(beanName)) {
            return (T) singletonObjects.get(beanName);
        }
        // 实例化对象入缓存
        Object obj = beanClass.newInstance();
        singletonObjects.put(beanName, obj);
        // 属性填充补全对象
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            Class<?> fieldClass = field.getType();
            String fieldBeanName = fieldClass.getSimpleName().toLowerCase();
            field.set(obj, singletonObjects.containsKey(fieldBeanName) ? singletonObjects.get(fieldBeanName) : getBean(fieldClass));
            field.setAccessible(false);
        }
        return (T) obj;
    }

}

class A {

    private B b;

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

class B {

    private A a;

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
}


Spring BeanFactory和FactoryBean的区别

BeanFactory提供了一系列的获取bean对象的方法。Object getBean(String name), T getBean(String name, Class requiredType)
FactoryBean实现了 FactoryBean 接口的类有能力改变 bean,具有代理作用.

BeanPostProcessor和BeanFactoryPostProcessor的区别

BeanFactoryPostProcessor它的实现类可以在当前BeanFactory初始化(spring容器加载bean定义文件)后,bean实例化之前修改bean的定义属性,达到影响之后实例化bean的效果
BeanPostProcessorpostProcessBeforeInitialization(Object bean, String beanName)和postProcessAfterInitialization(Object bean, String beanName)方法 作用:BeanPostProcessor能在spring容器实例化bean之后,在执行bean的初始化方法前后,修改bean的定义属性,达到影响之后实例化bean的效果

ResourceLoader和Resource的区别

Resource提供了统一的获取bean的定义方式。xml方式,url方式等
ResourceLoader进一步封装了用于获取Resource的方式。使得用户只需要传入路径,然后判断出是用那种方式获取。

ApplicationContext和BeanFactory获取bean的区别

ApplicationContextApplicationContext,如果配置的bean是singleton,那么不管你有没有或想不想用它,它都会被实例化(立即加载)
BeanFactoryBeanFactory实例化对象时,配置的bean不会马上被实例化,而是等到你使用该bean的时候(getBean)才会被实例化(懒加载)

Spring IOC流程分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建BeanFactory,并加载BeanDefinition

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

获取BeanFactory

在这里插入图片描述

未完待续-------------------------------

  • 28
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringIOC(Inverse of Control)实现原理是通过IOC容器来实现的。IOC容器负责实例化、定位、配置应用程序中的对象,并建立这些对象间的依赖关系,从而实现对象之间的松耦合。 在Spring中,通过配置文件或注解的方式告诉Spring哪些Bean需要进行管理,Spring会根据配置文件或注解来实例化这些Bean,并将它们放入IOC容器中。当我们需要使用这些Bean时,只需从IOC容器中获取即可,而不需要动创建对象。这样就实现了将控制对象创建的过程反转给Spring容器来管理的效果。 SpringIOC容器充当了一个类似于餐馆的角色,我们只需要告诉Spring哪些Bean需要进行管理,然后通过指定的方式从IOC容器中获取相应的Bean。Spring提供了多种类型的IOC容器,例如基于XML配置的ApplicationContext,基于注解的AnnotationConfigApplicationContext等等。无论使用哪种类型的IOC容器,Spring都会负责创建和管理Bean的生命周期,并根据依赖关系进行自动注入。 总结来说,SpringIOC实现原理是通过IOC容器管理Bean的实例化、定位和配置,实现对象之间的解耦,并提供便利的方式来获取和使用这些Bean。通过IOC容器,我们可以更加灵活地组织和管理应用程序的对象。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [springIoc实现原理](https://download.csdn.net/download/zhangcongyi420/11131211)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [一文带你深入剖析Spring IOC 实现原理](https://blog.csdn.net/SQY0809/article/details/118678588)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值