spring 容器

如果要深入了解spring的原来,那么最先了解得就应该是spring容器。Spring提供了两种类型的IOC容器实现:
1.beanFactory: IOC 容器的基本实现。
2.ApplicationContext: 提供了更多的高级特性,是beanFactory的子接口。
在spring的应用中,经常见到的代码就是如下典型的从容器中获取bean实例的代码:
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
OrderService service = (OrderService)ctx.getbean("personService");
第一行代码就是创建一个IOC容器的实例。BeanFactory、ApplicationContext只是接口,在应用中,需要实例化其实现类。ApplicationContext实现类有以下三种是经常要用到的:
ClassPathXmlApplicationContext: 从 classpath 下加载配置文件
FileSystemXmlApplicationContext: 从文件系统中加载配置文件
XmlWebApplicationContext: 只能用于 web 应用
无论使用何种方式, 配置文件时相同的。但是由于ApplicationContext提供了更多的附加功能,比如它提供了文本信息解析工具、载入资源的通用方法等等,所以使用的时候大部分都是用该接口。在web应用中通常都是通过ClassPathXmlApplicationContext去类路径下加载配置文件,生成一个IOC容器并管理配置文件中配置的bean。
Spring提供了强大的IOC容器来管理组成应用程序中的bean(组件)。要利用容器提供的服务,就必须配置bean,让这些bean运行在Spring IOC容器中。为了让Spring IOC 容器能够对bean进行实例化,每个bean 都应该提供一个唯一的名称和一个全限定类名。例如下面三种方式实例化bean:
1.使用类构造器实例化
<bean id="orderService" class="cn.itcast.OrderServiceBean"/>
2.使用静态工厂方法实例化
<bean id="personService" class="cn.itcast.service.OrderFactory" factory-
method="createOrder"/>
public class OrderFactory {
public static OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
3.使用实例工厂方法实例化:
<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-
method="createOrder"/>
public class OrderFactory {
public OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
第一种方法,IOC容易直接根据配置文件中的class属性通过反射创建一个实例,使用的是该类的默认构造方法。第二种则是调用class指定的工厂类的工厂方法,来返回一个相应的bean实例,值得注意的是工厂类的方法是静态方法,所以不用产生工厂本身的实例。而第三种则不同,它除了配置与第二种相同外,唯一的不同就是方法不是静态的,所以创建bean的实例对象时需要先生成工厂类的实例。
实例了bean对象时,需要对其中的属性也进行赋值,这时就是经常被提及的依赖注入。对bean的每个简单类型的属性来说,可以为其制定<value>元素。Spring会尝试将值转换为该属性的声明类型。比较常用的有:
1.setter注入使用<property>元素,使用name属性指定bean的属性名称。优点: setter 方法可以自动生成,简单。缺点: 组件使用者或许会忘记给组件注入它需要的依赖; 在第一次注入后,依赖可能会因为 setter 方法的调用而被修改。
2.构造器注入在 <constructor-arg>元素里声明属性,因为构造器的参数是基于位置的, 所以<constructor-arg>中没有name属性。优点: 解决了setter注入的缺点。缺点: 需通过参数位置来确定参数; 若组件有多个依赖需要注入, 会导致构造器参数列表非常冗长。
IOC容器里可能会声明很多的bean,这些bean之间的依赖关系通常会比较复杂。使用setter注入并不能保证属性一定会被注入。spring通过依赖检查来检查属性:
1.Spring 的依赖检查特性可以检查bean上的某些类型的所有属性是否被设置。
2.Spring 的依赖检查特性只需在<bean>的dependency-check 属性里指定依赖检查模式即可。
3.Spring 的依赖检查特性只能检查属性是否被设置,但对设置的属性值是 null 的情况则无能为力。
4.Spring 的依赖检查特性只对属性是否通过 setter 方法设置进行检查。 所以, 即使通过构造器
注入,依然会抛出异常。
以上是通过配置文件来检查,另外一种方式就是通过@Required注解检查属性。Spring的依赖检查特性只能检查某些类型的所有属性。不能只针对个别属性进行检查。
RequiredAnnotationbeanPostProcessor 是Spring的bean后置处理器,它检查所有具有@Required注解的属性是否已被设置。bean后置处理器是一种特殊类型的Spring bean,它能够在每个bean实例化后执行一些额外的工作。要激活bean后置处理器来进行属性检查,必须在Spring IOC容器里注册它。
RequiredAnnotationbeanPostProcessor只能检查属性是否被设置,但对设置的属性值是 null 的情况则无能为力。
### Spring容器的使用与原理 Spring容器Spring框架的核心组件,它通过IoC(控制反转)和DI(依赖注入)机制为开发者提供对象管理和依赖配置的功能[^1]。Spring容器的主要职责是管理Bean的生命周期、创建和装配依赖关系,从而让开发者可以专注于业务逻辑开发,而无需手动管理复杂的依赖关系。 #### 1. Spring容器的核心概念 Spring容器基于IoC(Inversion of Control)的设计理念,将对象的创建和依赖关系的管理从代码中分离出来,交由容器统一管理[^3]。这种设计降低了组件间的耦合度,提高了代码的可维护性和可测试性。在Spring中,IoC容器通过两种主要方式实现:`BeanFactory` 和 `ApplicationContext`[^2]。 - **BeanFactory**:这是Spring框架的基础基础设施,提供了基本的IoC功能。`BeanFactory` 是一个延迟加载的容器,只有在需要时才会实例化Bean。 - **ApplicationContext**:它是`BeanFactory`的扩展,提供了更多的企业级功能,例如AOP支持、国际化、事件传播等。`ApplicationContext`通常用于更复杂的场景。 #### 2. Spring容器的工作原理 Spring容器的工作原理可以分为以下几个关键步骤: - **BeanDefinition注册**:Spring容器会将所有的Bean定义信息(如类名、属性值、依赖关系等)解析并存储到一个Map结构中,这个Map就是所谓的容器[^4]。每个Bean都会被封装成一个`BeanDefinition`对象,其中包含了Bean的所有元数据信息。 - **Bean实例化**:当需要某个Bean时,Spring容器会根据`BeanDefinition`中的信息创建Bean实例。如果Bean有依赖关系,容器会自动解析并注入这些依赖。 - **依赖注入**:Spring容器通过构造函数注入、Setter方法注入或字段注入等方式,将依赖的Bean注入到目标Bean中。 - **生命周期管理**:Spring容器会管理Bean的整个生命周期,包括初始化、使用和销毁。开发者可以通过实现特定的接口(如`InitializingBean`、`DisposableBean`)或使用注解(如`@PostConstruct`、`@PreDestroy`)来定制Bean的生命周期行为。 #### 3. Spring容器的使用示例 以下是一个简单的Spring容器使用示例,展示如何通过`ApplicationContext`管理Bean。 ```java // 定义一个简单的Service类 public class GreetingService { public void greet() { System.out.println("Hello, Spring!"); } } // 配置文件(XML方式) <beans> <bean id="greetingService" class="com.example.GreetingService"/> </beans> // 使用Spring容器加载Bean public class MainApp { public static void main(String[] args) { // 创建Spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取Bean GreetingService greetingService = (GreetingService) context.getBean("greetingService"); // 调用方法 greetingService.greet(); } } ``` 在现代Spring应用中,更多地使用Java配置或注解方式替代XML配置。例如: ```java // 使用注解定义Bean @Component public class GreetingService { public void greet() { System.out.println("Hello, Spring!"); } } // 使用Spring容器加载Bean public class MainApp { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); GreetingService greetingService = context.getBean(GreetingService.class); greetingService.greet(); } } ``` #### 4. Spring容器的优势 - **降低耦合度**:通过IoC容器管理依赖关系,组件之间的耦合度显著降低。 - **提高可测试性**:依赖注入使得单元测试更加容易,因为可以轻松地替换依赖项。 - **简化开发**:Spring容器负责对象的创建和管理,开发者只需关注业务逻辑。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值