Spring复习-基于xml的bean配置

Spring实际就是将实例化控制反转给了BeanFactory,类都经过BeanFactory(读取xml后)进行实例化。
BeanFactory介绍
使用坐标spring-context

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.7</version>
</dependency>

xml中bean的定义方式

<bean id="userService" name="aaa,bbb" class="com.demo.service.impl.UserServiceImpl" scope="prototype">
    <!-- name通过方法前的set匹配,ref引用的是配置的bean id -->
    <property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="com.demo.dao.impl.UserDaoImpl"></bean>

bean id就是getBean中的参数name;name是别名,多个别名用","隔开;class配置的是类的路径名。
当有id时优先id赋值Name;无id有name时配置Name=第一个name参数;只有class时赋值Name=class.
bean中property配置实例化bean后就执行的方法,一般标签中的name和方法名有对应(方法名: setAaa->property name: Aaa),ref是xml中bean的引用。

ioc的两种客户端,ApplicationContext和BeanFactory。
(1)ApplicationContext基于BeanFactory实现,除此之外包含国际化等功能。
(2)ApplicationContext习惯命名xml为ApplicationContext.xml,
(3)ApplicationContext可以使用的客户端类有通过ClassPathXml(项目相对路径)和FileSystemXml(系统路径)两种实现类。BeanFactory通常使用DefaultListableBeanFactory配合XmlBeanDefinitionReader.两者获取Bean都是通过客户端调用getBean方法。
(4)BeanFactory是在getBean时才创建Bean示例,而ApplicationContext在编译后就实例化bean。

scope的两个属性:singleton和prototype,都是针对ApplicationContext而言的,对BeanFactory无效
(1)singleton是在初始化时就加载实例bean到容器,后面每次getBean获取的都是同一个实例
(2)prototype在初始化时不会将实例立即加入到bean到容器,而是在getBean后才实例化bean,且每次实例化都不一样

lazy-init属性是配置bean加载是不是懒加载,true->只有在getBean后才会创建实例,默认是false。
lazy-init=true时,scope取值singleton,变为每次getBean后才实例化,每次获取到的都是一个实例对象;scope取值prototype,还是getBean后才进行实例化,每次加载还是prototype原来的各个创建。

init-method、destroy-method
指定类初始化后、销毁后执行的方法名。
类实现InitializingBean接口、实现afterPropertiesSet后,完整的生命周期顺序:构造函数、bean中配置的property(setXxx方法)参数设置、afterPropertySet(InitializingBean接口的方法)、init-method指定的初始化方法。

Spring中的Bean实例化方式
ApplicationContext默认是通过BeanFactory进行创建,而BeanFactory是通过反射获取构造方法,调用构造方法进而实例化对象。
对于反射+构造方法的方式,分为有参构造和无参构造。对于有参构造函数需要在xml中进行配置。配置方式如下:

<bean id="userService" name="aaa,bbb" class="com.demo.service.impl.UserServiceImpl">
    <!-- 这里的constructor-arg代表构造实例的参数,不特指构造方法的参数 -->
    <constructor-arg name="name" value="aaa"></constructor-arg>
    <constructor-arg name="age" value="12"></constructor-arg>
</bean>

除了通过默认的BeanFactory实例化外,还可以通过自定义的BeanFactory来进行实例化。分为两种:
(1)静态工厂方法实例化bean:调用指定类的static方法即可。
(2)实例工厂方法实例化bean:实例化xml中配置的类,并调用指定方法进行实例化。
(3)实现FactoryBean规范的延时实例化方式:实现FactoryBean接口,只有在执行getBean时才会执行执行getObject方法获取实例化对象。

自定义实例化BeanFactory的好处:
(1)在创建对象的方法中可以写别的逻辑代码。
(2)对于一些第三方的jar包,可以在自定义的BeanFactory中调用它定义好的方法进行实例化,因为如果还通过xml实例化的话路径会很难找。

自定义BeanFactory的使用方法:
(1)编写一个类,类中写一个方法,方法中包含实例化的语句。如果使用静态工厂,方法就加static;如果使用示例工厂,方法就不用加static.
(2)xml中的配置如下:
静态工厂:只有一个工厂标签,参数配置factory-method指定方法即可。
实例工厂:一个工厂类的实例bean标签;一个工厂标签,参数配置factory-method指定方法、factory-bean指定工厂bean.
FactoryBean规范的工厂:不需要指定factory-method、factory-bean等参数。

<!-- 自定义静态工厂配置,id就是getBean的name参数,factory-method指定类的静态方法 -->
<bean id="userDao1" class="com.demo.factory.MyBeanFactory1" factory-method="userDao"></bean>
<!-- 自定义实例工厂配置,id就是getBean的name参数,factory-bean指定工厂实例方法 -->

<bean id="userDao2" factory-bean="myBeanFactory2" factory-method="userDao">
    <!-- 实例化方法的方法参数 -->
    <constructor-arg name="name" value="aaa"></constructor-arg>
</bean>
<!-- 自定义实例工厂实例类,先进行实例化 -->
<bean id="myBeanFactory2" class="com.demo.factory.MyBeanFactory2"></bean>
<!-- 自定义工厂实现FactoryBean接口 -->
<bean id="userDao3" class="com.demo.factory.MyBeanFactory3"></bean>

当需要实例化的bean需要注入数据类型为集合时,如下配置:

<bean id="userService" name="aaa,bbb" class="com.demo.service.impl.UserServiceImpl">
    <!-- name通过方法前的set匹配,ref引用的是配置的bean id -->
    <property name="userDao" ref="userDao"></property>
    <property name="stringList">
        <list>
            <value>aaa</value>
            <value>bbb</value>
        </list>
    </property>
    <property name="userDaoList">
        <list>
            <ref bean="userDaoEle1"></ref>
            <ref bean="userDaoEle2"></ref>
        </list>
    </property>
    <property name="stringSet">
        <set>
            <value>aaa</value>
            <value>bbb</value>
        </set>
    </property>
    <property name="userDaoSet">
        <set>
            <ref bean="userDaoEle1"></ref>
            <ref bean="userDaoEle2"></ref>
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="aaa" value-ref="userDaoEle1"></entry>
            <entry key="bbb" value-ref="userDaoEle2"></entry>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="aaa">aaa1</prop>
            <prop key="bbb">bbb1</prop>
        </props>
    </property>
</bean>

自动装配分为两种:根据类型、根据名称
根据类型(byType):根据bean中指定的class类型。当有多个相同类型但是不同名称的bean时,会报错。
根据名称(byName):根据bean中指定的id.当没有指定名称的bean时,会报错。

profile切换环境:可以定义多个beans标签,指定环境名称,在运行时可以进行切换。

<beans profile="dev">
    <bean id="userDao3" class="com.demo.dao.impl.UserDaoImpl"></bean>
</beans>
<beans profile="test">
    <bean id="userDao4" class="com.demo.dao.impl.UserDaoImpl"></bean>
</beans>

切换环境操作:
(1)方法1:ctrl+D指定环境:-Dspring.profiles.active=dev
(2)方法2:java语句

System.setProperty("spring.profiles.active","test");

当项目中有多个配置文件时,可以使用import标签引入指定配置文件,使用其中的bean

<import resource="ApplicaitonContext-user.xml"></import>

alias标签:为bean标签起别名

<alias name="userDao5" alias="aaa"></alias>
<alias name="userDao5" alias="bbb"></alias>
<alias name="userDao5" alias="ccc"></alias>

自定义命名标签的使用步骤:下面以spring-context为例
引入链接(xmlns:后的名称为自定义的,链接是第三方给定的):xmlns:context="http://www.springframework.org/schema/context"和xsi:schemaLocation中的http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-beans.xsd
使用标签:

<context:annotation-config></context:annotation-config>
posted @   Helix_node  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示