使用无参构造方法创建对象
应用场景
第三方依赖中某个类型没有提供构造方法时使用
实例工厂
容器中需要存在一个工厂实例
- <bean id="petFactory" class="com.xxx.factory.PetFactory"/>
- <bean id="pet" factory-bean="petFactory" factory-method="getPet">
-
-
- <constructor-arg name="choice" value="3"/>
- bean>
静态工厂
无需在容器中存在工厂实例
- <bean id="pet" class="com.woniuxy.factory.PetFactory" factory-method="getPet">
-
-
- <constructor-arg name="choice" value="2"/>
- bean>
要提供带参构造方法
- <bean id="pet" class="com.xxx.model.Pet">
- <constructor-arg name="pName" value="小狗"/>
- bean>
- <bean id="user" class="com.xxx.model.User">
-
-
-
-
-
-
- <constructor-arg name="uName" value="张三"/>
- <constructor-arg name="pet" ref="pet"/>
- bean>
要提供setter方法
- <bean id="pet" class="com.xxx.model.Pet">
- <property name="PName" value="小狗"/>
- bean>
- <bean id="user" class="com.xxx.model.User">
-
- <property name="UName" value="张三"/>
- <property name="pet" ref="pet"/>
- bean>
基本数据类型、String
标签中使用value属性完成赋值
在容器中注册过的bean
标签中使用ref属性来完成赋值
集合类型
- public class Pet {
- private String[] dogs;
- private List
cat; - private Set
mouse; - private Map
pig; - private Properties fish;
- }
- <bean id="pet" class="com.xxx.model.Pet">
-
- <property name="dog">
- <array>
- <bean class="java.lang.String">
- <constructor-arg value="dog1"/>
- bean>
- <bean class="java.lang.String">
- <constructor-arg value="dog2"/>
- bean>
- array>
- property>
-
- <property name="cat">
- <list>
- <bean class="java.lang.String">
- <constructor-arg value="cat1"/>
- bean>
- <bean class="java.lang.String">
- <constructor-arg value="cat2"/>
- bean>
- list>
- property>
-
- <property name="mouse">
- <set>
- <bean class="java.lang.String">
- <constructor-arg value="mouse1"/>
- bean>
- <bean class="java.lang.String">
- <constructor-arg value="mouse2"/>
- bean>
- set>
- property>
-
-
- <property name="pig">
- <map>
- <entry key="pig1">
- <bean class="java.lang.String">
- <constructor-arg value="pig-A"/>
- bean>
- entry>
- <entry key="pig2">
- <bean class="java.lang.String">
- <constructor-arg value="pig-B"/>
- bean>
- entry>
- map>
- property>
-
- <property name="fish">
- <props>
- <prop key="fish1">fish-Aprop>
- <prop key="fish2">fish-Bprop>
- props>
- property>
-
- bean>
factoryBean是使用工厂模式和简单装饰模式的bean
我们可通过它产生任意类型的对象
spring提供了一个接口factoryBean,该接口的泛型就是通过对应的factoryBean产生的对象的类型
- // 配置FactoryBean泛型类型
- public class UserFactoryBean implements FactoryBean
> {
- // 该方法的返回值就是在容器中配置了UserFactoryBean后,通过getBean()方法获得的对象
- public List
getObject() throws Exception { - return Arrays.asList("1","2","3");
- }
- // 该方法用于设置返回对象的数据类型
- public Class> getObjectType() {
- return List.class;
- }
- // 该方法用于设置getObject()返回值是否为单例(true:单例、false:多例)
- public boolean isSingleton() {
- return true;
- }
- }
<bean id="UserFactoryBean" class="com.xxx.factoryBean.UserFactoryBean"/>
spring提供封装好的factoryBean,主要接触的是用于产生集合的factoryBean
注意:list、set、map、properties有factoryBean,数组没有对应的factorBean
- <bean id="FactoryBean" class="org.springframework.beans.factory.config.ListFactoryBean">
-
-
- <property name="sourceList">
- <list>
- <value>1value>
- <value>2value>
- <value>3value>
- list>
- property>
-
-
- <property name="targetListClass" value="java.util.List"/>
- bean>
- <bean id="FactoryBean" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
-
-
- <property name="location" value="db.properties"/>
- bean>
beanFactory是用于创建和管理bean的工厂,是spring ioc容器的顶层接口
factoryBean是普通的bean,是factoryBean采用了工厂模式和简单装饰模式,可以使用它来创建一个其他类型的对象
简化setter注入操作
引入p命名空间后,在配置文件中可不用编写
标签,在bean标签上使用"p:属性名=值"方式完成对象属性赋值
配置文件的beans标签中添加:
xmlns:p="http://www.springframework.org/schema/p" 在bean标签上使用"p:属性名=值"的方式完成对象的成员变量赋值
<bean id="User" class="com.xxx.model.User" p:name="张三" p:age="23"/>
简化构造注入
引入c命名空间在配置文件中可不用编写
标签,在bean标签使用"c:属性名=值"完成对象赋值
配置文件的beans标签中添加:
xmlns:c="http://www.springframework.org/schema/c" 在bean标签上使用p:属性名=值的方式完成对象的成员变量的赋值操作
<bean id="User" class="com.xxx.model.User" c:name="王五" c:age="23"/>
用于在容器中注册集合的命名空间(list、set、map、properties)
配置文件的beans标签中添加:
- xmlns:util="http://www.springframework.org/schema/util"
- http://www.springframework.org/schema/util
- http://www.springframework.org/schema/util/spring-util.xsd
使用util命名空间完成容器中集合对象的注册
- <util:list id="list">
- <bean class="java.lang.String" c:value="张三"/>
- <bean class="java.lang.String" c:value="李四"/>
- <bean class="java.lang.String" c:value="王五"/>
- util:list>
- <util:properties id="properties" location="db.properties"/>
bean标签的scope属性决定bean的作用域,scope属性值:
singleton:单例(默认值)
prototype:原型模式,多例
request:每个请求都会生成一个新的实例,多例
session:每个会话都会生成一个新的实例,多例
globalSession:集群环境下才有可能用得到的值,多例(低版本spring才设置这个值)
单例的bean,生命周期与容器保持一致:容器创建,bean创建;容器关闭,bean销毁。
多例的bean,生命周期与容器无关:使用到该bean,才完成初始化;在GC(垃圾回收)时,才销毁。
- @NoArgsConstructor
- @AllArgsConstructor
- public class User {
- private String name;
- private String age;
- // 定制初始化方法
- public void state(){
- System.out.println("bean出生");
- }
- // 定制销毁方法
- public void end(){
- System.out.println("bean死亡");
- }
- }
- <bean id="bean" class="com.xxx.model.User" init-method="state" destroy-method="end" scope="singleton" c:name="张三" c:age="23"/>
- /*scope="singleton"*/
- // 容器创建,bean创建:bean出生
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
- // 容器关闭,bean销毁:bean死亡
- context.close();
- // 无反应
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
- // 完成初始化:bean出生
- System.out.println(context.getBean("bean"));
- // 无反应
- context.close();
spring配置文件中,通过在bean标签设置autowire属性,然后设置自动装配策略,当容器启动时,spring会自动为某个需要进行属性设置的对象成员变量进行自动装配:从容器中去找到一个符合要求的对象并且装配到某个对象的成员变量中。
autowire属性取值:
| 属性 | 作用 |
|---|---|
| no | 不进行自动装配(默认值) |
| default | 使用父级标签的自动装配策略 |
| byName | 根据成员变量名称去容器找一个bean的id值与之相匹配的bean,赋值给对应成员变量 |
| byType | 根据成员变量类型去容器中找一个bean的class值与之相匹配的bean,赋值给对应成员变量 |
| constructor | 根据构造方法形参类型找一个bean的class值与之相匹配的bean,赋值给对应成员变量(本质上是byType策略) |
注意
使用byType进行自动装配,有可能由于容器中存在多个相同类型的bean,而导致无法实现准确自动装配,从而报异常
解决方案:在进行自动装配时,把自动装配时不需要的bean排除掉,排除需要在bean标签上使用autowire-candidate属性,取值为false
spring的自动装配使用XML配置很死板,不灵活。在开发中用注解配置
- public class User {
- private String uName;
- private Pet pet;
- }
- <bean id="pet1" class="com.xxx.model.Pet" c:pName="小狗" c:pAge="2" autowire-candidate="false" />
- <bean id="pet2" class="com.xxx.model.Pet" c:pName="小猫" c:pAge="3"/>
- <bean id="user" class="com.xxx.model.User" autowire="byType">
- <property name="uName" value="张三"/>
- bean>