spring类加载方式解析

概要

若是有问题,请及时联系我咱们及时沟通共同进步?谢谢!

Spring框架通过各种方式加载多种类型的Bean定义,并将这些定义转换成内部统一的数据结构进行管理和存储,通常这样的存储结构可以视作一个高级别的“Map”。在需要时,可以直接从Spring IoC容器中获取Bean实例。重要的是要理解,尽管容器的操作(如获取Bean)是通过方法调用来实现的,并且这些方法调用本身不会修改方法的内部逻辑或行为,但Spring IoC容器的设计确保了其操作是线程安全的。因此,多个线程可以同时安全地从容器中获取Bean,无需担心线程安全问题。然而,这并不意味着从容器中获取的Bean自身也是线程安全的;
Bean的线程安全性需要根据其具体实现和业务逻辑来单独考虑。

spring类加载方式5种(常见):仅描述

一、使用XML配置文件加载类:

1. 具体步骤:编写XML配置文件,定义需要加载的Bean及其属性。在应用程序中,通过ApplicationContext或其他容器类来读取这个配置文件,并实例化Bean。

2. 配置方法:在XML文件中使用< bean> 标签定义Bean,包括其id、class属性等。
3. 适用场景:适用于需要明确配置和集中管理Bean的情况。
4. 适用场景:适用于需要明确配置和集中管理Bean的情况。
5. 优缺点:优点在于配置明确、可读性强。缺点在于当Bean数量较多时,配置文件可能变得庞大且难以维护。

二、使用注解加载类:

1. 具体步骤:在类上使用如@Component、@Service、@Controller等注解来标识。Spring在启动时,会扫描指定的包,并自动加载这些被注解的类。

2. 配置方法:在Spring的配置文件中开启组件扫描,指定需要扫描的包路径。
3. 适用场景:适用于快速开发和减少配置工作量的情况。
4. 优缺点:优点在于方便快捷,减少了繁琐的配置。缺点在于可能不如XML配置那么直观和明确。

三、自动扫描加载类:

1. 具体步骤:在Spring配置中设置自动扫描的包路径,Spring会自动扫描并加载这些路径下的类。

2. 配置方法:在配置文件中使用< context:component-scan>标签指定扫描的包。
3. 适用场景:适用于大型项目,可以自动发现和加载新的Bean。
4. 优缺点:优点在于自动化程度高,便于扩展。缺点在于可能导致不必要的类被加载,增加启动时间。

四、通过Java配置类加载:

1. 具体步骤:使用@Configuration注解的Java类来定义Bean。在这些类中,可以使用@Bean注解来定义和初始化Bean。

2. 配置方法:创建一个带有@Configuration注解的Java类,并在其中定义和配置Bean。
3. 适用场景:适用于喜欢Java代码配置或需要更灵活配置的情况。
4. 优缺点:优点在于配置灵活、强大。缺点在于对Java代码的理解要求较高。

五、Web应用程序中的特定加载方式:

1. 具体步骤:将applicationContext.xml放在WEB-INF/classes下,或者通过在web.xml中配置ContextLoaderListener或ContextLoaderServlet来指定加载路径。

2. 配置方法:在web.xml中添加相应的< listener>或< servlet>配置。
3. 适用场景:适用于Web应用程序,特别是需要与Web服务器集成的情况。
4. 优缺点:优点在于与Web应用程序的紧密集成。缺点在于配置相对复杂,且依赖于Web服务器的部署方式。。

六、不常用的加载方式:

1、使用FactoryBean
Spring允许使用FactoryBean来生成特定的Bean。FactoryBean是一个接口,当在Spring上下文中定义一个FactoryBean时,它将返回一个不同的Bean实例,而不是FactoryBean本身的实例。
2、使用Profile
Spring Profiles提供了一种方式来将Bean的注册条件化,这意味着可以根据不同的环境(如开发、测试、生产)来决定是否加载某个Bean。
3、通过XML的< import>标签组织配置
当配置非常庞大时,可以使用< import>标签将配置分散到多个XML文件中,从而提高可维护性。
4、使用Spring表达式语言(SpEL)
在某些情况下,可以在XML配置或注解中使用SpEL来动态指定Bean的属性值或者进行复杂的条件化配置。
5、使用外部化配置
通过@PropertySource注解和Environment接口,可以加载外部配置文件中的属性,这些属性可以用来配置Bean。
6、通过编程方式动态注册Bean
Spring的ApplicationContext接口提供了一些方法,允许在运行时通过编程方式动态添加Bean到Spring容器中。

核心类关系:

1. Spring IOC的核心接口:

BeanFactory:

是Spring IOC容器的根接口,用于获取bean对象。

ApplicationContext:

是BeanFactory的子接口,添加了更多企业特定的功能,如简化配置信息的访问、事件发布等。

ListableBeanFactory:

是一个可以枚举所有bean实例,而不是尝试按名称一个个地查询bean的工厂。

AutowireCapableBeanFactory:

提供自动装配的能力,是Spring的自动装配的核心。

2.核心抽象类:

AbstractApplicationContext:

实现了ApplicationContext接口,提供了Spring容器的基本功能。

AbstractBeanFactory:

继承自DefaultSingletonBeanRegistry,实现了BeanFactory接口,提供了对Bean定义的基本管理和依赖注入的功能。

3. 核心类及其来源:

ClassPathXmlApplicationContext(来自AbstractApplicationContext):

从类路径下的XML配置文件中加载容器定义。

FileSystemXmlApplicationContext(来自AbstractApplicationContext):

从文件系统的XML配置文件中加载容器定义。

AnnotationConfigApplicationContext(来自AbstractApplicationContext):

从一个或多个基于Java的配置类中加载Spring应用上下文。

DefaultListableBeanFactory(来自AbstractAutowireCapableBeanFactory和ListableBeanFactory):

是Spring容器的默认实现,用于管理bean的定义、创建、和依赖关系注入。

4. 核心方法及作用:

getBean(String name)(BeanFactory):

根据bean的名字,获取一个bean实例。

refresh()(AbstractApplicationContext):

刷新容器,加载或刷新配置信息。

registerBeanDefinition(String beanName, BeanDefinition beanDefinition)(DefaultListableBeanFactory):

注册Bean定义。

scan(String… basePackages)(AnnotationConfigApplicationContext):

扫描给定的包以及子包,查找注解@Component、@Service等,进行bean定义。

5. 继承关系描述:

BeanFactory接口

最基本的容器功能定义,ApplicationContext在此基础上增加了更多企业级的支持。

ListableBeanFactory和AutowireCapableBeanFactory

BeanFactory的扩展,提供了更丰富的容器管理功能。

AbstractApplicationContext是一个抽象类,

实现了ApplicationContext接口,所有的应用上下文如ClassPathXmlApplicationContext、FileSystemXmlApplicationContext和AnnotationConfigApplicationContext都是从AbstractApplicationContext继承而来。

AbstractBeanFactory是对BeanFactory接口的基本实现,而DefaultListableBeanFactory则是在此基础上提供了更完整的功能。

6. 接口、抽象类、类的继承关系:

接口层级:

BeanFactory:

是最基础的容器接口,定义了容器的最基本形式。

ListableBeanFactory:

扩展自BeanFactory,添加了枚举所有bean实例的能力。

AutowireCapableBeanFactory:

也是扩展自BeanFactory,添加了自动装配bean的能力。

ApplicationContext:

继承自ListableBeanFactory和HierarchicalBeanFactory(后者也是BeanFactory的子接口),在BeanFactory的基础上增加了应用级别的服务。

抽象类和类实现:

AbstractBeanFactory:

实现了BeanFactory接口的部分功能,是其他具体BeanFactory实现的基类。

DefaultListableBeanFactory:

从AbstractAutowireCapableBeanFactory继承,并实现了ListableBeanFactory和AutowireCapableBeanFactory接口,是Spring中最核心的一个BeanFactory实现。

AbstractApplicationContext:

实现了ApplicationContext接口,提供了ApplicationContext的标准功能。这个类不直接与BeanFactory的层次结构相连,但内部使用BeanFactory实现,通常是DefaultListableBeanFactory。

ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext 等:

这些都是AbstractApplicationContext的具体实现,分别支持从类路径下的XML文件、文件系统中的XML文件以及Java注解配置来加载Spring容器。

关系:

BeanFactory (接口): IoC容器的基本接口  
    ListableBeanFactory (接口): 增加了列举Bean的功能  
    AutowireCapableBeanFactory (接口): 增加了自动装配Bean的功能  
    HierarchicalBeanFactory (接口): 允许容器存在父子关系  
        ApplicationContext (接口): 提供了更多企业级特性  
            AbstractApplicationContext (抽象类): ApplicationContext的抽象实现  
                ClassPathXmlApplicationContext (): 从类路径XML加载Bean  
                FileSystemXmlApplicationContext (): 从文件系统XML加载Bean  
                AnnotationConfigApplicationContext (): 从注解配置加载Bean

小结

无论通过哪种方式加载,Spring都会对Bean进行以下处理:

1、解析与注册:首先,Spring会解析配置文件、注解或Java配置类,提取出Bean的定义信息,并将其注册到Spring容器中。
2、实例化:根据Bean的定义,Spring会创建Bean的实例。这通常是通过反射调用Bean的构造器来完成的。
3、属性填充:Spring会自动为Bean填充属性,这包括通过依赖注入将其他Bean注入到当前Bean中,以及设置Bean的其他属性。
4、初始化:在Bean实例化并填充属性后,Spring会调用Bean的初始化方法,如@PostConstruct注解的方法,以完成Bean的初始化工作。

最终,这些处理过的Bean实例会被存储在Spring容器的内部缓存中。这个缓存通常是一个Map结构,以Bean的名称或类型为键,以Bean的实例为值。这样,当应用程序需要某个Bean时,Spring可以快速地从缓存中检索并返回该Bean的实例。

公共流程

1、读取配置:无论是XML、注解、Java配置类还是Web应用程序中的特定配置,Spring都需要首先读取这些配置信息。
2、解析配置:Spring会解析读取到的配置,提取出Bean的定义信息,包括Bean的名称、类型、属性等。
3、注册Bean:根据解析出的Bean定义信息,Spring会在内部注册这些Bean,准备进行后续的实例化和初始化工作。
4、实例化与初始化:如前所述,Spring会根据注册的Bean定义来实例化Bean,并填充其属性,然后调用初始化方法。
5、存储与管理:实例化并初始化完成的Bean会被存储到Spring容器的缓存中,以便后续使用和管理。

思想先行:
任重而道远仁以为己任

  • 18
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring 中,可以使用动态加载类的方式来实现在运行时动态加载和管理类。下面介绍两种常见的动态加载类的方式: 1. 使用 `Class.forName()` 方法加载类:`Class.forName(className)` 方法可以根据类的全限定名(className)动态加载类。一旦类加载完成,就可以使用反射来创建该类的实例并进行相关操作。 示例代码如下所示: ```java String className = "com.example.MyClass"; Class<?> clazz = Class.forName(className); Object instance = clazz.newInstance(); ``` 在这个例子中,我们使用 `Class.forName()` 方法加载了名为 `com.example.MyClass` 的类,并通过反射创建了该类的实例。 2. 使用 `ClassLoader` 加载类:`ClassLoader` 是 Java 虚拟机提供的用于加载类文件的机制。Spring 中的 `ApplicationContext` 本身就是一个 `ClassLoader`,可以使用它来加载类。 示例代码如下所示: ```java ApplicationContext context = ...; // 获取 ApplicationContext 对象 ClassLoader classLoader = context.getClassLoader(); String className = "com.example.MyClass"; Class<?> clazz = classLoader.loadClass(className); Object instance = clazz.newInstance(); ``` 在这个例子中,我们通过 `ApplicationContext` 获取了一个 `ClassLoader`,然后使用它来加载名为 `com.example.MyClass` 的类,并通过反射创建了该类的实例。 需要注意的是,动态加载类需要在运行时提供正确的类名,并且需要确保类路径中存在该类的字节码文件。另外,动态加载类的方式在设计和使用时需要谨慎,确保符合项目需求和安全性要求。 希望以上信息对你有所帮助,如果你有任何疑问,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值