spring配置文件属性说明
一、bean的内置属性
1、id属性
id为bean的唯一标识名,就是常说的beanName。它必须是合法的XMLID,在整个XML文档中唯一。name属性:用来为bean id创建一个或多个别名(这里是别名不是beanName),它可以是任意的字母符合,多个别名之间用逗号或空格分开。如果没有定义bean的id,那么第一个别名就会被作为id;如果也没有定义name,那么自动生成一个id和一个别名(这时的别名为类的全类名且类名首子母小写)。
2、class属性:
用来定义类的全限定名(包名+类名)。只有子类Bean不用定义该属性。
3、parent属性
子类Bean定义它所引用它的父类Bean。这时class属性失效。子类Bean会继承父类Bean的所有属性,子类Bean也可以覆盖父类Bean的属性。注意:子类Bean和父类Bean是同一个Java类。
4、abstract属性
默认为”false”,用来定义Bean是否为抽象Bean。它表示这个Bean将不会被实例化,一般用于父类Bean,因为父类Bean主要是供子类Bean继承使用。
5、scope 属性
默认为singleton(单例)。如果设prototype(原型)状态,BeanFactory将为每次Bean请求创建一个新的Bean实例。
6、lazy-init属性
用来定义这个Bean是否实现懒初始化。默认为“default” ,如果为“true”,它将在BeanFactory启动时初始化所有的SingletonBean。反之,如果为“false”,它只在Bean请求时才开始创建SingletonBean。
7、autowire属性
它定义了Bean的自动装载方式。
1、“no”:不使用自动装配功能。
2、“byName”:通过Bean的属性名实现自动装配。
3、“byType”:通过Bean的类型实现自动装配。
4、“constructor”:类似于byType,但它是用于构造函数的参数的自动组装。
5、“default”:默认值,自动装配。
8、depends-on属性
1 | @DependsOn |
这个Bean在初始化时依赖的对象,这个对象会在这个Bean初始化之前创建。
9、init-method属性
用来定义Bean的初始化方法,它会在Bean组装之后调用。它必须是一个无参数的方法。
10、destroy-method属性
用来定义Bean的销毁方法,它在BeanFactory关闭时调用。同样,它也必须是一个无参数的方法。它只能应用于singletonBean。
11、factory-method属性
定义创建该Bean对象的工厂方法。它用于下面的“factory-bean”,表示这个Bean是通过工厂方法创建。此时,“class”属性失效。
12、factory-bean属性:
定义创建该Bean对象的工厂类。如果使用了“factory-bean”则“class”属性失效。
二、bean的子元素
1、meta:元数据
当需要使用里面的信息时可以通过key获取
a.元数据的应用场景
一个公共工程中的Spring配置文件,可能会被多个工程引用。因为每个工程可能只需要公共工程中的一部分Bean,所以这些工程的Spring容器启动时,需要区分开哪些Bean要创建出来。(在各种工程实现中,Spring Bean激活哪些bean的方案)
b.解决
1)、xml样例
1 | <bean name="xmlPageManager"class="org.apache.jetspeed.page.psml.CastorXmlPageManager"init-method="init" destroy-method="destroy"> |
2)、bean过滤器:
JetspeedBeanDefinitionFilter在Spring容器解析每个Bean定义时,会取出上面Bean配置中j2:cat对应的值,例如dbPageManageror pageSerializer。然后将这部分作为正则表达式与当前的Key(从配置文件中读出)进行匹配。只有匹配上的Bean,才会被Spring容器创建出来。
1 | public boolean match(BeanDefinition bd) { |
match()方法中的CATEGORY_META_KEY的值就是j2:cat,matcher类中保存的就是当前的Key,并负责将当前Key与每个Bean的进行正则表达式匹配。
registerDynamicAlias的作用是:在Bean匹配成功后,定制的Spring容器会调用此方法为Bean注册别名。详见下面1.3中的源码。
3)、.定制Spring容器
定制一个Spring容器,重写registerBeanDefinition()方法,在Spring注册Bean时进行拦截。
1 | public class FilteringXmlWebApplicationContextextends XmlWebApplicationContext { |
4)、最后
使用BeanReferenceFactoryBean工厂Bean,将上面配置的两个Bean(xmlPageManager和dbPageManager)包装起来。将Key配成各自的,实现通过配置当前Key来切换两种实现。别名都配成一个,这样引用他们的Bean就直接引用这个别名就行了。例如下面的PageLayoutComponent。
1 | <bean class="org.springframework.beans.factory.config.BeanReferenceFactoryBean"> |
2、lookup-method
获取器注入,是把一个方法声明为返回某种类型的 bean 但实际要返回的 bean 是在配置文件里面配置的。该方法可以用于设计一些可插拔的功能上,解除程序依赖。
a.场景说明
spring默认Bean 都是 singleton 的。如果singleton 依赖 singleton、prototype 依赖 prototype 直接设置属性依赖即可。可是如果在singleton的bean中依赖了prototype的bean,就会出现,单例bean中的原型bean每次获取的都是同一个对象。现在的目标是每次调用start方法,都会实例化一个新的prototypeBean,有如下几种方案:
1、原始样例
1 |
|
1 |
|
2、解决
方案1:实现ApplicationContextAware接口
每次获取依赖的原型 bean 从 BeanFactory 中取,即实现ApplicationContextAware接口。不推荐:原因在于但是如果用ApplicationContextAware接口,就让我们与Spring代码耦合了,违背了反转控制原则(IoC,即bean完全由Spring容器管理,我们自己的代码只需要用bean就可以了)。
java方式
1 |
|
方案2:lookup方法注入
该方法利用cglib动态生成一个SingletonServiceImpl的子类,该子类会自动override有lookup注解的方法,代码干净整洁。
1 |
|
xml方式
1 | <!-- 这是个非单例模式的bean --> |
方案3:使用动态代理
spring提供了动态代理,在注入PrototypeBean时会先注入一个PrototypeBean的代理类,等方法调用时,由代理类分配具体的实例,还是先看代码:
1 |
|
1 | //如果是接口,就使用ScopeProxyMode.INTERFACES |
重点来了,请注意PrototypeBean的注解中,scope我使用了request。为什么不使用prototype呢,因为在动态代理时,如果使用prototype,对prototypeBean中方法的每一次调用,都会生成一个新的prototypeBean实例,如果scope使用prototype,则会出现下面的情况:
1 | public void start(){ |
3、replaced-method
可以在运行时调用新的方法替换现有的方法,还能动态的更新原有方法的逻辑。
使用spaM的reimplement方法替换spaQ的name方法,通过cglib代理
1 | <bean id="spaQ" class="com.dianping.SpaQ"> |
SpaM必须实现接口import org.springframework.beans.factory.support.MethodReplacer;
1 | public class SpaM implements MethodReplacer { |
4、constructor-arg
对bean自动寻找对应的构造函数,并在初始化的时候将设置的参数传入进去
1 | public class StudentService { |
1 | <bean id="bookService" class="org.springframework.core.service.BookService"/> |
StudentService 定义一个构造函数,配置文件中使用 constructor-arg
元素对其配置,该元素可以实现对 StudentService 自动寻找对应的构造函数,并在初始化的时候将值当做参数进行设置。
5、property
5.1基本数据类型赋值
▶name属性:用于指定属性的名称,与类中的set方法后方的名称一致
▶value属性:用于指定该属性的值,用于指定的值是基本类型、字符串类型
▶ref属性:用于指定该属性的值,用于指定的值是引用对象类型(即其他的Bean),ref后面的值为另一个Bean的id
▶value标签:用于指定属性的值,类型为基本类型、字符串类型,值为标签内的文本内容,可以使用null值将属性的值设置为null
▶ref标签:用于指定属性的值,类型为引用对象类型,值为其属性的值,其属性有以下三种:
▷local属性:用于指定依赖本地Bean实例,即同一XML文件中定义的Bean
▷bean属性:用于指定依赖的Bean实例,可以是不同XML文件中的Bean
▷parent属性:用于指定依赖的Bean实例,可以是当前BeanFactory或ApplicationContext的父BeanFactory或ApplicationContext中的Bean
1 | <!-- in the child (descendant) context --> |
以下是针对集合的标签
▶list标签:用于声明该依赖对象为一个list集合,其下用value和ref标签来指定list中的各值(基本、字符串、对象等)
▷value标签:用于指定list集合中的值,指定的值为基本类型、字符串类型,值为文本内容
▷ref标签:用于指定list集合中的引用值,指定的值为其他的对象Bean,其用法与之前property标签下的ref标签的用法相同
▶set标签:用于声明该依赖对象为一个set集合,其用法与list标签相同。
▶map标签:用于声明该依赖对象为一个map集合,其下用entry标签来声明一个键值对
▷entry标签:用于声明map集合下的一个键值对,其下用key属性指明键,value/ref标签指明值
→key属性:用于指明键值对中的键,它一般为字符串
→value标签:用于指明键值对中的值,类型为基本类型、字符串类型
→ref标签:用于指明键值对中的值,类型为引用对象类型,即其他的Bean,其用法同之前的ref标签
1 | <bean id="studentService" class="org.springframework.core.service.StudentService"> |
1 | <bean id="moreComplexObject" class="example.ComplexObject"> |
6、qualifier
通过Qualifier指定注入bean的名称
6.1使用说明
@Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常
@Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,具体使用方式如下
1 | //注解使用 |
1 | //参数方式 |
样例
1 | <qualifier type="org.springframework.beans.factory.annotation.Qualifier" value="限定标识符"/> |
其中type属性可选,指定类型,默认就是Qualifier注解类,name就是给Bean候选者指定限定标识符,一个Bean定义中只允许指定类型不同的
1 | <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource"> |
6.2、扩展@Qualifier限定描述符注解(不带参数)
对@Qualifier的扩展来提供细粒度选择候选者;
ex:具体使用方式就是自定义一个注解并使用@Qualifier注解其即可使用。
a、场景:
首先让我们考虑这样一个问题,如果我们有两个数据源,分别为Mysql和Oracle,因此注入两者相关资源时就牵扯到数据库相关,如在DAO层注入SessionFactory时,当然可以采用前边介绍的方式,但为了简单和直观我们希望采用自定义注解方式。
b、实现
1,2,创建注解和实用类:
1 | package com.annotation; |
1 | public class TestBean { |
3、在Spring配置文件 添加如下Bean配置:
1 | <bean id="testBean" class="com.bean.TestBean"/> |
4、在Spring修改定义的两个数据源:
1 | <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource"> |
5、测试方法如下:
1 |
|
6.3、扩展@Qualifier限定描述符注解(带参数)
对@Qualifier的扩展来提供细粒度选择候选者;
前边演示了不带属性的注解,接下来演示一下带参数的注解:
1、首先定义数据库类型:
1 | package com.enumBean; |
2、其次扩展@Qualifier限定描述符注解
1 | package com.annotation; |
3、准备测试Bean:
1 | package com.bean; |
4、在Spring配置文件 添加如下Bean配置:
1 | <bean id="testBean" class="com.bean.TestBean"/> |
5、在Spring修改定义的两个数据源:
1 | <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource"> |
6、测试方法如下:
1 |
|
测试也通过了,说明我们扩展的@Qualifier限定描述符注解也能很好工作。
三、引用
https://www.programmersought.com/article/26812163811/
https://blog.csdn.net/qq_33374723/article/details/78752364
https://blog.csdn.net/hong10086/article/details/83214554
http://www.webkf.net/article/32/64241.html
https://blog.csdn.net/u011120159/article/details/82218472
http://www.voidcn.com/article/p-vdgrbkrm-bqu.html
- 本文作者: 初心
- 本文链接: http://funzzz.fun/2021/01/04/spring配置参数(IOC)/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!