创建Bean的几种方式
1. 通过反射调用构造方法创建bean对象
调用类的构造方法获取对应的bean实例,是使用最多的方式,这种方式只需要在xml bean元素中指定class属性,spring容器内部会自动调用该类型的构造方法来创建bean对象,将其放在容器中以供使用。
<bean id="bean名称" name="bean名称或者别名" class="bean的完整类型名称">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="1" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="2" value="bean的值" ref="引用的bean名称" />
....
<constructor-arg index="n" value="bean的值" ref="引用的bean名称" />
</bean>
- constructor-arg用于指定构造方法参数的值
- index:构造方法中参数的位置,从0开始,依次递增
- value:指定参数的值
- ref:当插入的值为容器内其他bean的时候,这个值为容器中对应bean的名称
2. 通过静态工厂方法创建bean对象
我们可以创建静态工厂,内部提供一些静态方法来生成所需要的对象,将这些静态方法创建的对象交给spring以供使用。
<bean id="bean名称" name="" class="静态工厂完整类名" factory-method="静态工厂的方法">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="1" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="2" value="bean的值" ref="引用的bean名称" />
....
<constructor-arg index="n" value="bean的值" ref="引用的bean名称" />
</bean>
<bean id="bean名称" name="" class="静态工厂完整类名" factory-method="静态工厂的方法">
<property name="name" value=""/>
<property name="age" value=""/>
</bean>
- class:指定静态工厂完整的类名
- factory-method:静态工厂中的静态方法,返回需要的对象。
- constructor-arg用于指定静态方法参数的值,用法和上面介绍的构造方法一样
3. 通过实例工厂方法创建bean对象
让spring容器去调用某些对象的某些实例方法来生成bean对象放在容器中以供使用。
<bean id="bean名称" factory-bean="需要调用的实例对象bean名称" factory-method="bean对象中的方法">
<constructor-arg index="0" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="1" value="bean的值" ref="引用的bean名称" />
<constructor-arg index="2" value="bean的值" ref="引用的bean名称" />
....
<constructor-arg index="n" value="bean的值" ref="引用的bean名称" />
</bean>
spring容器以factory-bean的值为bean名称查找对应的bean对象,然后调用该对象中factory-method属性值指定的方法,
将这个方法返回的对象作为当前bean对象放在容器中供使用
4. 通过FactoryBean创建bean对象
public class UserFactoryBean implements FactoryBean<UserModel> {
int count = 1;
@Nullable
@Override
public UserModel getObject() throws Exception { //@1
UserModel userModel = new UserModel();
userModel.setName("我是通过FactoryBean创建的第"+count+++ "对象");//@4
return userModel;
}
@Nullable
@Override
public Class<?> getObjectType() {
return UserModel.class; //@2
}
@Override
public boolean isSingleton() {
return true; //@3
}
}
Bean标签
Property | 释义 |
---|---|
class | 类的全限定名 |
name | 可指定 id、name(用逗号、分号、空格分隔) |
scope | 作用域 |
constructor arguments | 指定构造参数 |
properties | 设置属性的值 |
autowiring mode | no(默认值)、byName、byType、 constructor |
lazy-initialization mode | 是否懒加载(如果被非懒加载的bean依赖了那么其实也就不能懒加载了) |
initialization method | bean 属性设置完成后,会调用这个方法 |
destruction method | bean 销毁后的回调方法 |
Bean的作用域
当在Spring中定义一个bean时,你必须声明该Bean的作用域的选项。Spring框架支持以下五个作用域,分别为singleton、proptotype、request、session和global session,5种作用域。
作用域 | 描述 |
---|---|
singleton | 在spring IOC容器仅存在一个Bean示例,Bean以单例方式存在,默认值 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XXBean() |
request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于webApplicationContext环境 |
session | 同一个HTTP session请求都会创建一个新的bean,不同的session使用不同的Bean,仅适用于WebApplicationContext环境 |
global-session(application) | 一般用于protlet应用环境,该运用域仅适用于WebApplicationContext环境 |
signleton作用域
singleton是默认的作用域,也就是说,当定义Bean时,如果没有指定作用域配置项,则Bean的作用域被默认为signleton。
当一个bean的作用域为singleton,那么spring ioc容器中只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该bean定义相匹配,则置灰返回bean的同一实例。
也就是说,当将一个Bean定义设为singleton作用域的时候,SpringIOC容器只会创建该bean定义的唯一实例。
singleton是单例模式,就是在创建器容器时就同时自动创建了一个Bean对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,singleton作用域是spring中的缺省作用域。
protoType作用域:
当一个Bean的作用域为Propertype,表示一个bean定义对应多个对象实例。protoType作用域会导致在每次请求对该Bean请求时都会创建一个新的Bean实例。
prototype是原形类型,它在我们创建容器的时候并没有实例化。而是当我们获取Bean的时候才去创建一个对象,而且我们每次获取到的对象都不是同一个对象。
request作用域:
当一个bean的作用域为request,表示在一次http请求中,一个bean对应一个实例;对每个http请求都会创建一个bean实例,request结束的时候,这个bean也就结束了,request作用域用在spring容器的web环境中。
session作用域:
这个和request类似,也是用在web环境中,session级别共享的bean,每个会话会对应一个bean实例,不同的session对应不同的bean实例。
Application作用域:
全局web应用级别的作用于,也是在web环境中使用的,一个web应用程序对应一个bean实例,通常情况下和singleton效果类似的,不过也有不一样的地方,singleton是每个spring容器中只有一个bean实例,一般我们的程序只有一个spring容器,但是,一个应用程序中可以创建多个spring容器,不同的容器中可以存在同名的bean,但是sope=aplication的时候,不管应用中有多少个spring容器,这个应用中同名的bean只有一个。
注入方式
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Food {
private String name;
private double price;
private User user;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
构造器注入
- 1、根据构造器参数索引注入
<bean id="user" class="xxx.User">
<constructor-arg index="0" value="张三"/>
<constructor-arg index="1" vlue="19”/>
</bean>
constructor-arg用户指定构造器的参数
index:构造器参数的位置,从0开始
value:构造器参数的值,value只能用来给简单的类型设置值,
value对应的属性类型只能为byte,int,long,float,double,boolean,Byte,Long,Float,Double,枚举,
spring容器内部注入的时候会将value的值转换为对应的类型。
- 2、 根据构造器参数类型注入
<bean id="user" class="xxx.User">
<constructor-arg type="String" value="zhangsan"/>
<constructor-arg type="int" value="20"/>
</bean>
constructor-arg用户指定构造器的参数
type:构造函数参数的完整类型,如:java.lang.String,int,double
value:构造器参数的值,value只能用来给简单的类型设置值
- 3、根据构造器参数名称注入
<bean id="user" class="xxx.User">
<constructor-arg name="String" value="zhangsan"/>
<constructor-arg name="int" value="20"/>
</bean>
constructor-arg用户指定构造器的参数 name:构造参数名称 value:构造器参数的值,value只能用来给简单的类型设置值
set方法注入
• get/set方法
<bean id="user" class="xxxx.User">
<property name="name" value="xxx"/>
<property name="age" value="13"/>
</bean>
<bean id="food" class="xxxx.Food">
<property name="name" value="branana"/>
<property name="price" value="1.3"/>
<property name="user" ref="user"/>
</bean>
• 实例工厂注入
<!-- 声明实例工厂bean,Spring容器需要先创建一个SimpleFactory对象,才能调用工厂方法 -->
<bean id="factory" class="cn.tewuyiang.factory.SimpleFactory" />
<!--
通过实例工厂的工厂方法,创建三个bean,通过factory-bean指定工厂对象,
通过factory-method指定需要调用的工厂方法
-->
<bean id="name" factory-bean="factory" factory-method="getName" />
<bean id="age" factory-bean="factory" factory-method="getAge" />
<bean id="car" factory-bean="factory" factory-method="getCar" />
<bean id="user" class="cn.tewuyiang.pojo.User">
<!-- 将上面通过实例工厂方法创建的bean,注入到user中 -->
<property name="name" ref="name"/>
<property name="age" ref="age"/>
<property name="car" ref="car"/>
</bean>
• 注解注入
• @Autowired
• @Resource
• @Value