spring · 2024-10-31 0

spring 手动注册 bean

一、配置

1.pom

<properties>
    <spring.version>5.1.9.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>

2.配置文件

<?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
            http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

3.测试

也可定义 BeanFactoryPostProcessor,在其中执行 registerSingleton(beanName, singletonObject)

public class MyMain {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-conf.xml");

        Object object = new Object();
        context.getBeanFactory().registerSingleton("object", object);

        Object newObject = context.getBean("object");
        System.out.println(newObject == object);
    }
}

二、原理

1.注册 bean

执行 this.singletonObjects.put(beanName, singletonObject)、this.registeredSingletons.add(beanName)、this.singletonFactories.remove(beanName)、this.earlySingletonObjects.remove(beanName)

// DefaultListableBeanFactory.java
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
    ...
    synchronized (this.singletonObjects) {
        Object oldObject = this.singletonObjects.get(beanName);
        if (oldObject != null) {
            throw new IllegalStateException("Could not register object [" + singletonObject +
                    "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
        }
        addSingleton(beanName, singletonObject);
    }
}

protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        this.singletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
    }
}

2.获得 bean

从 this.singletonObjects 获得 bean

// DefaultListableBeanFactory.java
@Override
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    Object sharedInstance = getSingleton(beanName);
    ...
}

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        ...
    }
    return singletonObject;
}