【手写Easy-Spring|1】

Spring Bean工厂原理与类关系详解

一、核心概念

1.1 Bean

Bean是由Spring容器管理的对象,可以是任何Java类的实例。Spring容器负责Bean的创建、初始化、配置和管理生命周期。

1.2 Bean工厂

Bean工厂(BeanFactory)是Spring框架中负责创建和管理Bean的核心组件,主要职责包括:

  • 管理Bean的定义信息
  • 创建Bean实例
  • 管理Bean的生命周期
  • 处理Bean之间的依赖关系

1.3 Bean定义

BeanDefinition是描述Bean元数据信息的对象,包含创建Bean所需的所有信息:

  • Bean的类型(Class)
  • Bean的作用域(单例、原型等)
  • Bean的初始化方法
  • Bean的销毁方法
  • Bean的依赖关系

二、核心接口与类

2.1 BeanFactory接口

BeanFactory是Bean工厂的顶级接口,定义了获取Bean的基本方法。

复制代码
public interface BeanFactory {
    Object getBean(String beanName) throws BeansException;
    Object getBean(String beanName, Object... args) throws BeansException;
}

2.2 BeanDefinition类

BeanDefinition类定义了Bean的元数据信息。

复制代码
public class BeanDefinition {
    private Class beanClass;

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

    public Class getBeanClass() {
        return beanClass;
    }

    public void setBeanClass(Class beanClass) {
        this.beanClass = beanClass;
    }
}

2.3 BeansException类

BeansException是Spring中处理Bean相关异常的基类。

复制代码
public class BeansException extends RuntimeException {
    public BeansException() {
        super();
    }

    public BeansException(String message) {
        super(message);
    }

    public BeansException(String message, Throwable cause) {
        super(message, cause);
    }
}

三、实现类详解

3.1 DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistry是SingletonBeanRegistry接口的默认实现,使用HashMap存储单例Bean实例。

复制代码
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
    private Map<String, Object> singletonObjects = new HashMap<>();

    @Override
    public void registerSingleton(String beanName, Object singleton) {
        singletonObjects.put(beanName, singleton);
    }

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

3.2 AbstractBeanFactory

AbstractBeanFactory是BeanFactory接口的抽象实现,继承自DefaultSingletonBeanRegistry。它实现了Bean的获取逻辑,管理单例Bean的缓存,并定义了创建Bean的抽象方法。

复制代码
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
    @Override
    public Object getBean(String beanName) throws BeansException {
        Object singleton = getSingleton(beanName);
        if (singleton != null) {
            return singleton;
        }
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        return createBean(beanName, beanDefinition);
    }

    @Override
    public Object getBean(String beanName, Object... args) throws BeansException {
        Object singleton = getSingleton(beanName);
        if (singleton != null) {
            return singleton;
        }
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        return createBean(beanName, beanDefinition, args);
    }

    protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException;
    protected abstract Object createBean(String beanName, BeanDefinition beanDefinition, Object... args) throws BeansException;
}

3.3 AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory实现了创建Bean的具体逻辑,使用InstantiationStrategy接口来创建Bean实例。

复制代码
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
    private InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy();

    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {
        return createBean(beanName, beanDefinition, null);
    }

    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition, Object... args) throws BeansException {
        Object bean = null;
        try {
            bean = createBeanInstance(beanDefinition, beanName, args);
        } catch (Exception e) {
            throw new BeansException("Instantiation of bean failed", e);
        }
        registerSingleton(beanName, bean);
        return bean;
    }

    protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object... args) throws BeansException {
        Constructor constructor = null;
        Class<?> beanClass = beanDefinition.getBeanClass();
        Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
        for (Constructor<?> ctor : declaredConstructors) {
            if (args != null && ctor.getParameterTypes().length == args.length) {
                constructor = ctor;
                break;
            }
        }
        return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructor, args);
    }

    public InstantiationStrategy getInstantiationStrategy() {
        return instantiationStrategy;
    }

    public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
        this.instantiationStrategy = instantiationStrategy;
    }
}

3.4 DefaultListableBeanFactory

DefaultListableBeanFactory是Spring Bean工厂的核心实现类,实现了BeanDefinitionRegistry接口和继承了AbstractAutowireCapableBeanFactory。

复制代码
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
    protected 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;
    }
}

3.5 InstantiationStrategy接口及实现

InstantiationStrategy接口定义了Bean实例化的策略,有两个实现类:

SimpleInstantiationStrategy:使用Java反射机制创建Bean实例。

复制代码
public class SimpleInstantiationStrategy implements InstantiationStrategy {
    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        Class<?> beanClass = beanDefinition.getBeanClass();
        try {
            if (ctor != null) {
                return beanClass.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
            } else {
                return beanClass.getDeclaredConstructor().newInstance();
            }
        } catch (Exception e) {
            throw new BeansException("Failed to instantiate [" + beanClass.getName() + "]", e);
        }
    }
}

CglibInstantiationStrategy:使用Cglib库创建Bean实例,支持更复杂的场景。

复制代码
public class CglibInstantiationStrategy implements InstantiationStrategy {
    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        try {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(beanDefinition.getBeanClass());
            enhancer.setCallback(new NoOp() {
                @Override
                public int hashCode() {
                    return super.hashCode();
                }
            });
            if (ctor != null) {
                return enhancer.create(ctor.getParameterTypes(), args);
            } else {
                return enhancer.create();
            }
        } catch (Exception e) {
            throw new BeansException("Failed to instantiate [" + beanDefinition.getBeanClass().getName() + "]", e);
        }
    }
}

四、类关系图

4.1 继承关系

复制代码
BeanFactory
    ↑
AbstractBeanFactory
    ↑
AbstractAutowireCapableBeanFactory
    ↑
DefaultListableBeanFactory

DefaultSingletonBeanRegistry
    ↑
AbstractBeanFactory

4.2 实现关系

  • DefaultListableBeanFactory implements BeanDefinitionRegistry
  • DefaultSingletonBeanRegistry implements SingletonBeanRegistry
  • SimpleInstantiationStrategy implements InstantiationStrategy
  • CglibInstantiationStrategy implements InstantiationStrategy

4.3 组合关系

  • AbstractAutowireCapableBeanFactory组合了InstantiationStrategy
  • DefaultListableBeanFactory组合了BeanDefinition的存储

五、Bean生命周期

5.1 生命周期阶段

  1. Bean定义阶段:通过BeanDefinition描述Bean的元数据信息
  2. Bean注册阶段:将BeanDefinition注册到BeanDefinitionRegistry中
  3. Bean实例化阶段:根据BeanDefinition创建Bean实例
  4. Bean初始化阶段:对Bean实例进行初始化,如设置属性、处理依赖注入等
  5. Bean使用阶段:Bean实例被应用程序使用
  6. Bean销毁阶段:Bean实例被销毁(单例Bean)

5.2 实例化策略

  1. 使用无参构造函数:如果Bean类有无参构造函数,直接使用反射创建实例
  2. 使用带参构造函数:如果Bean类只有带参构造函数,使用反射或Cglib创建实例
  3. 使用工厂方法:通过指定的工厂方法创建实例
  4. 使用工厂Bean:通过实现FactoryBean接口的Bean创建实例

六、Bean作用域

6.1 单例作用域(Singleton)

Spring的默认作用域,一个Bean定义在Spring容器中只会创建一个实例,所有对该Bean的请求都会返回同一个实例。

优点 :节省内存、提高性能、共享状态
缺点:线程安全问题、状态管理复杂

6.2 原型作用域(Prototype)

每次请求Bean时都会创建一个新的实例,适用于需要频繁创建和销毁的对象。

优点 :线程安全、状态隔离
缺点:内存消耗大、性能较低

6.3 Web应用作用域

  • Request:每个HTTP请求创建一个新的Bean实例
  • Session:每个HTTP会话创建一个新的Bean实例
  • GlobalSession:每个全局HTTP会话创建一个新的Bean实例(Portlet应用)

七、依赖注入

7.1 构造函数注入

通过Bean的构造函数来注入依赖关系。

复制代码
public class UserService {
    private final UserDao userDao;
    
    @Autowired
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
}

优点:确保Bean在创建时就拥有所有必要的依赖、避免了循环依赖、提高了代码的可读性和可测试性

7.2 Setter方法注入

通过Bean的Setter方法来注入依赖关系。

复制代码
public class UserService {
    private UserDao userDao;
    
    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

优点:支持可选依赖、支持依赖的动态修改、简化了单元测试

7.3 字段注入

通过注解直接注入到Bean的字段中。

复制代码
public class UserService {
    @Autowired
    private UserDao userDao;
}

优点 :代码简洁、减少了样板代码
缺点:破坏了封装性、使依赖关系不明确、难以进行单元测试

八、自动装配

8.1 自动装配模式

  • no:默认值,不进行自动装配
  • byName:根据属性名称自动装配
  • byType:根据属性类型自动装配
  • constructor:根据构造函数参数类型自动装配
  • autodetect:自动检测使用constructor或byType模式

8.2 优缺点

优点 :减少手动配置的工作量、提高配置的可读性和可维护性、减少配置错误的可能性
缺点:依赖关系不够明确、可能导致意外的依赖注入、不支持复杂的依赖关系

九、工作原理

9.1 初始化阶段

  1. 加载配置:Spring容器加载配置文件或注解,解析Bean定义
  2. 注册Bean定义:将解析后的Bean定义注册到BeanDefinitionRegistry中
  3. 初始化单例Bean:对于单例作用域的Bean,在容器启动时就创建实例

9.2 获取Bean阶段

  1. 检查缓存:首先检查单例缓存中是否存在Bean实例
  2. 创建Bean :如果缓存中不存在,则创建Bean实例
    • 获取Bean定义
    • 实例化Bean
    • 初始化Bean
    • 缓存单例Bean
  3. 返回Bean:返回Bean实例给调用者

9.3 销毁阶段

  1. 关闭容器:当应用程序关闭时,关闭Spring容器
  2. 销毁单例Bean:调用单例Bean的销毁方法

十、应用示例

10.1 基本使用

复制代码
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
beanFactory.registerBeanDefinition("userService", beanDefinition);
UserService userService = (UserService) beanFactory.getBean("userService");
userService.queryUserInfo();

10.2 带参数的构造函数

复制代码
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinition beanDefinition = new BeanDefinition(UserServiceWithConstructor.class);
beanFactory.registerBeanDefinition("userServiceWithConstructor", beanDefinition);
UserServiceWithConstructor userService = (UserServiceWithConstructor) beanFactory.getBean("userServiceWithConstructor", "test", 25);
userService.queryUserInfo();

10.3 使用不同的实例化策略

复制代码
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
((AbstractAutowireCapableBeanFactory) beanFactory).setInstantiationStrategy(new CglibInstantiationStrategy());
BeanDefinition beanDefinition = new BeanDefinition(UserServiceWithConstructor.class);
beanFactory.registerBeanDefinition("userServiceWithConstructor", beanDefinition);
UserServiceWithConstructor userService = (UserServiceWithConstructor) beanFactory.getBean("userServiceWithConstructor", "test", 25);
userService.queryUserInfo();

十一、扩展点

11.1 自定义BeanPostProcessor

允许在Bean初始化前后对Bean进行处理。

复制代码
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Before initialization: " + beanName);
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("After initialization: " + beanName);
        return bean;
    }
}

11.2 自定义FactoryBean

允许自定义Bean的创建过程。

复制代码
public class MyFactoryBean implements FactoryBean<UserService> {
    @Override
    public UserService getObject() throws Exception {
        return new UserService();
    }
    
    @Override
    public Class<?> getObjectType() {
        return UserService.class;
    }
    
    @Override
    public boolean isSingleton() {
        return true;
    }
}

11.3 自定义InstantiationStrategy

允许自定义Bean的实例化策略。

复制代码
public class MyInstantiationStrategy implements InstantiationStrategy {
    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException {
        System.out.println("Instantiating bean: " + beanName);
        Class<?> beanClass = beanDefinition.getBeanClass();
        try {
            if (ctor != null) {
                return beanClass.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args);
            } else {
                return beanClass.getDeclaredConstructor().newInstance();
            }
        } catch (Exception e) {
            throw new BeansException("Failed to instantiate [" + beanClass.getName() + "]", e);
        }
    }
}

十二、最佳实践

12.1 使用注解配置

注解配置更加简洁、直观。

复制代码
@Component
public class UserService {
}

@Configuration
@ComponentScan("com.example")
public class AppConfig {
}

12.2 合理使用作用域

  • 对于无状态的Bean,使用单例作用域
  • 对于有状态的Bean,使用原型作用域
  • 对于Web应用,根据需要使用request、session等作用域

12.3 避免循环依赖

循环依赖是指两个或多个Bean之间相互依赖,Spring可以处理构造函数注入以外的循环依赖,但最好避免。

12.4 使用构造函数注入

构造函数注入是Spring推荐的依赖注入方式,它可以确保Bean在创建时就拥有所有必要的依赖。

12.5 使用@Qualifier注解

当存在多个同类型的Bean时,使用@Qualifier注解指定要注入的Bean名称。

复制代码
@Component
public class UserService {
    private final UserDao userDao;
    
    @Autowired
    public UserService(@Qualifier("userDaoImpl") UserDao userDao) {
        this.userDao = userDao;
    }
}

12.6 使用@Value注解

使用@Value注解注入配置值,提高配置的灵活性。

复制代码
@Component
public class UserService {
    @Value("${user.service.name}")
    private String name;
}

十三、常见问题与解决方案

13.1 NoSuchBeanDefinitionException

原因 :找不到指定名称的Bean定义
解决方案:检查Bean名称是否正确、检查Bean是否已注册、检查配置是否正确

13.2 BeanCreationException

原因 :Bean创建失败
解决方案:检查Bean的构造函数是否正确、检查Bean的依赖是否存在、检查Bean的初始化方法是否正确

13.3 UnsatisfiedDependencyException

原因 :依赖注入失败
解决方案:检查依赖的Bean是否存在、检查依赖的类型是否匹配、检查自动装配的配置是否正确

13.4 CircularDependencyException

原因 :循环依赖
解决方案:重构代码消除循环依赖、使用Setter方法注入代替构造函数注入、使用@Lazy注解延迟加载

13.5 NoClassDefFoundError

原因 :找不到类定义
解决方案:检查依赖是否正确、检查类路径是否正确、检查版本是否兼容

13.6 IllegalArgumentException

原因 :参数非法
解决方案:检查方法参数是否正确、检查配置值是否正确、检查Bean定义是否正确

十四、总结

Spring Bean工厂是Spring框架的核心组件,它通过管理Bean的定义、创建和生命周期,为应用程序提供了一种灵活、可配置的对象管理机制。

核心优势

  • 灵活性:支持多种配置方式和实例化策略
  • 可扩展性:提供了丰富的扩展点
  • 可靠性:成熟稳定的实现
  • 易用性:简洁直观的API

通过理解Spring Bean工厂的原理和类与类之间的关系,开发者可以更好地掌握Spring框架的工作机制,构建高质量的应用程序。作为开发者,我们应该不断学习和掌握Spring框架的新特性和最佳实践,以提高开发效率和代码质量。

相关推荐
今天多喝热水2 小时前
Lua脚本实现滑动窗口
java·开发语言·lua
Grassto2 小时前
HTTP请求超时?大数据量下的网关超时问题处理方案,流式处理,附go语言实现
后端·http·golang·go
没有bug.的程序员2 小时前
Spring Cloud Gateway:API网关限流与熔断实战
java·开发语言·数据库·spring boot·gateway·api·springcloud
Paul_09202 小时前
golang编程题2
开发语言·后端·golang
代码N年归来仍是新手村成员2 小时前
【Go】从defer关键字到锁
开发语言·后端·golang
亓才孓2 小时前
JVM栈帧和堆存储什么类型的数据的分析
java·开发语言
肖。35487870942 小时前
窗口半初始化导致的BadTokenException闪退!解决纯Java开发的安卓软件开局闪退!具体表现为存储中的缓存为0和数据为0。
android·java·javascript·css·html
QQ588501982 小时前
springboot地区特色农产品团购商城平台 小程序
spring boot·后端·小程序
wniuniu_3 小时前
运维运维运维
java·运维·dubbo