Spring-Bean必须知道的那些事

创建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 modeno(默认值)、byName、byType、 constructor
lazy-initialization mode是否懒加载(如果被非懒加载的bean依赖了那么其实也就不能懒加载了)
initialization methodbean 属性设置完成后,会调用这个方法
destruction methodbean 销毁后的回调方法
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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值