一、Spring中bean实例的创建方式
①调用构造器创建Bean实例
大多数情况下,BeanFactory直接通过new关键字调用构造器来创建Bean实例,而class属性指定了Bean实例的实现类。Spring对Bean实例的所有属性执行默认初始化,即所有基本类型的值初始化为0或false,所有引用类型的值初始化为null,接下来,BeanFactory会根据配置文件决定依赖关系,先实例化被依赖的Bean实例,然后为Bean注入依赖关系,最后将一个完整的Bean实例返回给程序。
②使用静态工厂方法创建Bean
使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类。Spring需要知道由哪个静态工厂方法来创建Bean实例
class:该属性的值为静态工厂类的类名
factory-method:该属性指定生产Bean实例的静态工厂方法,如果方法需要参数,则使用<constructor-arg.../>元素传入
当我们指定Spring使用静态工厂方法来创建Bean实例时,Spring将先解析配置文件,并根据配置文件指定的信息,通过反射调用静态工厂类的静态工厂方法,将该静态工厂方法的返回值作为Bean实例。在这个过程中,Spring不再负责创建Bean实例,Bean实例时由用户提供的静态工厂类负责创建的。当实例被建成后,Spring依然可以管理该Bean实例的依赖关闭,包括为其注入所需的依赖关系、管理其生命周期等。
③调用实例工厂方法创建Bean
实例工厂方法与静态工厂方法只有一点不同:调用静态工厂方法只需使用工厂类即可,调用实例工厂方法则必须使用工厂实例。
factory-bean:该属性的值为工厂Bean的id
factor-method:该属性指定实例工厂的工厂方法,如果方法需要参数,则使用<constructor-arg.../>元素传入
二、深入理解容器中的Bean
①抽象Bean和子Bean
抽象Bean和一般Bean没有区别,只是在配置文件中指定abstract=“true”,当程序采用ApplicationContext作为Spring容器,程序实例化ApplicationContext容器时会默认实例化singleton Bean,但不会初始化abstract=true的Bean
通过给一个元素指定parent属性即可指定该Bean是一个子Bean,parent属性指定该Bean所继承的父Bean的id。子Bean可以从父Bean定义继承实现类、依赖关系等配置信息,子Bean也可覆盖父Bean的配置信息
此处的Bean继承与Java中通俗的继承有区别:①Spring中Bean继承只是实例之间的关系,主要表现为参数值的延续,而Java中的继承是类之间的关系,主要表现为方法、属性的延续②Spring中的子Bean不可作为父Bean使用,不具备多态性,Java中的子类实例完全可当成父类实例使用③Spring中的子Bean和父Bean可以是不同类型,但Java中的继承则可保证子类是一种特殊父类
注意:被标注成abstract=true的类并不一定要真的是abstract类,这种抽象bean和子bean主要用于,当系统中bean增多,并且大部分bean的配置信息相同时,可定义一个抽象的模板类,把这些共同的配置信息写在模板类中,然后让其他的bean继承此模板bean即可
②容器中的工厂Bean
此处的工厂Bean与前面介绍的实例工厂方法创建Bean或静态工厂方法创建Bean的工厂有所区别:前面那些工厂是标准的工厂模式,Spring只是负责调用工厂方法来创建Bean实例;此处的工厂Bean是Spring的一种特殊Bean,这种工厂Bean必须实现FactoryBean接口。
FactoryBean接口是工厂Bean的标准接口,实现该接口的Bean通常只能作为工厂Bean使用,当我们将工厂Bean部署在容器中,并通过getBean()方法来获取工厂Bean时,容器不会返回FactoryBean实例,而是返回FactoryBean的产品
FactoryBean接口提供如下三个方法:
→T getObject():实现该方法负责返回该工厂Bean生成的Java实例。
→Class<?>getObjectType():实现该方法返回该工厂Bean生成的Java实例的实现类
→boolean isSingleton():实现该方法表示该工厂Bean生成的Java实例是否为单例模式
部署工厂Bean与部署普通Bean其实没有任何区别,只是通过id获取的不是工厂Bean,而是工厂Bean产生的产品Bean。
FactoryBean是Spring中非常有用的一个接口,Spring内置提供了很多实用的工厂Bean,例如TransactionProxyFactoryBean等,这个工厂Bean专门用于为目标Bean创建事物代理
③获取bean本身id
前面我们接触到的都是通过id得到Bean实例,而有时候我们知道Bean实例却不知道它的id,要想得到id可以让Bean实现接口BeanNameAware,通过实现方法setBeanName(由Spring容器自己调用)得到id
④强制化初始Bean
Spring默认有个规则,总是先初始化要被注入的Bean,再初始化要实例化的Bean,可以通过设置depends-on强制指定先初始化哪个Bean
对于singleton作用域的Bean,Spring容器知道Bean何时实例化结束、何时销毁,Spring可以管理实例化结束之后和销毁之前的行为。管理Bean的生命周期行为主要有如下两个时机:
①注入依赖关系之后
Spring提供两种方式在Bean全部属性设置成功后执行特定行为:使用init-method属性(推荐,代码污染小);实现InitializingBean接口(实现接口方法afterPropertiesSet() throws Exception),如果两种方式都使用的话,容器在设置完属性后,先执行InitializingBean接口中定义的方法,然后执行init-method属性指定的方法。
②即将销毁Bean之前
Spring提供两种方法定制Bean实例销毁之前的特定行为,:使用destroy-method属性(推荐,代码污染小);实现DisposableBean接口(实现接口方法destroy() throws Exception),如果两种方法都使用,容器在实例销毁之前,先执行DisposableBean接口中定义的方法,然后执行destroy-method属性指定的方法。
singleton作用域的Bean通常会随容器的关闭而销毁,但问题是:ApplicationContext容器在什么时候关闭呢?在基于Web的ApplicationContext实现中,系统已经提供了相应的代码保证关闭Web应用时恰当地关闭Spring容器;如果处于一个非Web应用的环境下,为了让Spring容器优雅地关闭,并调用singleton Bean上的相应析构回调方法
如果容器中很多bean都需要指定生命周期方法,则可利用<beans../>元素的default-init-method属性和default-destroy-method属性
需要指出的是,当Bean实现了ApplicationContextAware接口、BeanNameAware接口之后,Spring容器会在该Bean初始化完成之后--也就是调用init-method属性所指定的方法(如果有)之后,再来回调setApplicationContext(ApplicationContext applicationContext)、setBeanName(String name)方法
由于singleton Bean具有单例行为,当客户端多次请求singleton Bean时,Spring返回给客户端的将是同一个singleton Bean实例,这不存在任何问题。问题是:如果客户端多次请求singleton Bean、并调用该singleton Bean去调用prototype Bean的方法时-----始终都是调用同一个prototype Bean实例,这就违背了设置prototype Bean的初衷:本来希望它具有prototype行为,但实际上它却表现出singleton行为了。
解决这种不同步问题有如下两种思路:
→部分放弃依赖注入:singleton作用域Bean每次需要prototype作用域Bean时,主动向容器请求新的Bean实例,即可保证每次注入的prototype Bean实例都是最新的实例(代码污染)
→利用方法注入(使用lookup),利用lookup方法注入可以让Spring容器重写容器中Bean的抽象或具体方法,返回查找容器中其他Bean的结果,被查找的Bean通常是一个non-singletong Bean(尽管也可以是一个singleton的)。
例:在要依赖prototype Bean的singleton Bean中定义个abstract get方法,然后在配置文件中<lookup-method name="get" bean="prototypeBeanid"/>
四、深入理解依赖关系配置
Spring不仅支持普通的值注入和依赖于其他已知Bean的注入,还支持将Bean实例的属性值、方法返回值、Field值直接定义成容器中的一个变量
①注入其他Bean的属性值 使用PropertyPathFactoryBean,例<bean id="person.son.age“ class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>这种配置方式下的id不是该Bean的唯一标识,而是指定属性表达式值
②注入其他Bean的Field 使用FieldRetrievingFactoryBean,例<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE“ class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>,field既可以是静态的也可以是动态的(对应targetObject)
③注入其他Bean的方法返回值 使用MethodInvokingFactoryBean 例<bean id="sysProps“ class="org.springframework.beans.factory.config.MethodInvokingFactoryBean "><property name="targetClass" value="java.lang.System"/><property name="targetMethod" value="getProperties"/></bean> method既可以是静态方法,也可以是非静态的(对应targetObject)
相关推荐
这个“spring最基本jar”可能包含了Spring框架的基础组件,如Spring Core、Spring Beans、Spring AOP等,是学习和使用Spring框架的基础。理解并掌握这些知识点,能够帮助开发者有效地利用Spring框架构建高效、稳定的...
标题提到的“springsecurity基本的三个jar包”是Spring Security的核心组件,它们构成了框架的基础架构,使得开发者能够实现各种安全需求。 1. **spring-security-core.jar**: 这个jar包包含了Spring Security的...
本篇文章将详细探讨Spring的基本配置,帮助你深入理解如何在项目中设置和使用Spring。 一、Spring配置概述 Spring的配置方式主要有两种:XML配置和Java配置。早期,XML配置是主流,而现在,随着Spring Boot的兴起...
总的来说,理解并掌握这些基本包的用法是学习和使用Spring的第一步。通过IoC和AOP,Spring能够帮助我们构建松耦合、易于维护的Java应用。在实际开发中,结合Spring Boot和其他相关技术,可以极大地提高开发效率和...
本文将深入探讨Spring装配基本属性的原理,帮助你更好地理解如何在代码中使用和配置这些属性。 首先,Spring装配的基本方式有两种:XML装配和基于注解的装配。XML装配是早期版本Spring的主要装配方式,通过`<bean>`...
Spring的基础jar包包含了运行Spring应用程序所需的核心组件,使得开发者能够快速搭建Spring环境并开始使用其基本功能。下面我们将深入探讨Spring框架的一些核心知识点。 1. **依赖注入(Dependency Injection, DI)...
展示了spring cloud的基本用法。包括:1)一个基本的spring boot应用。2)分布式配置管理服务端。3)分布式配置管理客户端(微服务应用)。4)服务注册服务端。5)服务注册发现客户端(微服务应用)。6)实现spring ...
### Spring框架概述 ...通过本教程的学习,您将能够掌握Spring框架的基本原理和使用方法,为进一步深入研究打下坚实的基础。无论是在构建简单的Web应用还是复杂的分布式系统,Spring框架都能够为您提供强大的支持。
4. **初始化**:Spring容器调用Bean的初始化方法,完成对象的初始化。 5. **Bean管理**:Spring容器负责Bean的生命周期管理,包括销毁等操作。 **六、应用场景** Spring Ioc广泛应用于各种项目中,如: - 数据...
这个项目很可能是用来演示 Spring MVC 的基本用法,包含了一个简单的 Controller、视图页面和配置文件。通过分析这些文件,你可以更好地理解 Spring MVC 的工作原理和配置方式。 总的来说,Spring MVC 提供了一种...
Spring 框架是 JavaEE 开发中的一个核心组件,由 Rod Johnson 在其著作...通过这个“spring-framework基本包”,我们可以学习并掌握 Spring 框架的核心概念和使用方式,为开发高质量的 JavaEE 应用奠定坚实基础。
### 二、Spring 基本使用 1. **配置 Spring**:可以通过 XML 文件或注解方式进行配置。XML 配置中,`<bean>` 元素用于定义 Bean,`<property>` 用于注入依赖。注解配置则使用如 `@Configuration` 和 `@...
Spring可以通过AOP代理来实现切面,也可以使用AspectJ的编译时或加载时织入,增强代码功能。 八、Spring Boot Spring Boot是近年来流行的快速启动Spring应用的方式,它默认配置了许多常见功能,减少了大量配置工作...
1. 创建项目和配置文件:在使用 Spring IOC 之前,需要创建一个项目并配置相关的依赖项。pom.xml 文件是 Maven 项目的核心配置文件,用于管理项目的依赖项。在 pom.xml 文件中,需要添加 Spring IOC 相关的依赖项,...
Spring 三种依赖注入方式 Spring 框架中提供了多种依赖注入方式,其中最常用的三种依赖注入方式分别是接口注入、设值注入和构造函数...同时,我们也需要了解 Spring 配置文件的基本内容,以便更好地使用 Spring 框架。
Spring MVC 中的 RequestMapping 6个基本用法小结 Spring MVC 是一个基于 Java 的 Web 应用程序框架,提供了强大的 RequestMapping 机制来处理 HTTP 请求。在 Spring MVC 中,RequestMapping 是一个核心组件,负责...
**Spring定时器TimerTask用法** 在Java世界中,`java.util.Timer` 和 `java.util.TimerTask` 是用于实现定时任务的基本工具,但它们在多线程环境中的表现并不理想,容易引发内存泄漏。Spring框架提供了更强大的定时...
以上就是Spring WebFlux的基本使用和关键概念,结合提供的"boot-webflux"项目,你可以进一步探索更多细节,包括路由定义、过滤器、中间件、自定义异常处理、反应式数据访问等功能,从而全面掌握Spring WebFlux在实际...
这里提到的"spring3核心包及第三方插件包"是该书实践部分所需的基础组件,包含了Spring框架的基本模块以及一些常用的第三方扩展。 首先,Spring3的核心包主要包括以下几个部分: 1. **Spring Core**:这是Spring...