Spring Bean 的基本配置

Posted 红颜莫知己

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Bean 的基本配置相关的知识,希望对你有一定的参考价值。

1.Spring中set方法的注入

User实体

@Data
//lombok提供的有参构造
@AllArgsConstructor
lombok提供的无参构造
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private int age;
    private String sex;
    private String birthday;

}

beanFactory.xml

<bean id="user" class="edu.xalead.User">
        <property name="id" value="1806"/>
        <property name="name">
            <value>张三</value>
        </property>
        <property name="sex" value=""/>
        <property name="age" value="18"/>
        <property name="birthday" value="2000-1-1"/>
    </bean>

1.1set的两种注入方法

我们在xml文件中注入的时候我们可以写成这样:

<property name="id" value="1806"/>

也可以写成这样:

<property name="id">
   <value>1806</value>
</property>

这没什么区别的,不过我们一般使用前者,毕竟看起来代码少,也方便

代码测试:

@Test
    public void test3(){
        //创建工厂
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("beanFactory.xml");
        //从工厂中拿配置好的UserServlet实例
        User user = beanFactory.getBean(User.class);
        System.out.println(user);
    }

在这里插入图片描述

1.2type属性

有事我们在注入的时候有时候会看到type:

<property name="id">
   <value type="int">1806</value>
</property>

这相当于一个类型声明,声明value是什么类型的数据,然后调用类型转换器将我们写入的字符串转换为我们我们所定义的类型。但其实这是一个多余的,当我们注入的时候,会通过User对象进行反射从而知道是什么类型。

1.3Date()类型的注入

但有一些特殊的类型是Spring所没有的,需要我们自己去定义,就比如Date类型,如果我们这样写就会报错

 private Date birthday;
 <property name="birthday" value="2000-1-1"/>

在这里插入图片描述
Spring是没有这个的转换器,将字符串转换为Date类型,所以其实我们可以直接用String来写,或者new Date(),但是后者约束性太大,不能得到我们想要的日期,还是前者方便。

2.Spring_scop

当我们在测试案例中创建两个User实例时,进行检查发现,这两个实例其实是一个

BeanFactory beanFactory = new ClassPathXmlApplicationContext("beanFactory.xml");
//从工厂中拿配置好的UserServlet实例
User user = beanFactory.getBean(User.class);
User user1 = beanFactory.getBean(User.class);
System.out.println(user == user1);

在这里插入图片描述
如果我们要创建多例模式,就要使用到属性scope

scope属性有两个值:

  1. singleton(默认情况下,即单例模式)
  2. prototype(多例模式)
 <bean id="user" class="edu.xalead.User" scope="prototype">

我们在进行测试答案为false

3.自动注入(autowire)

我们在userServlet中注入userDao

<bean id="userDao" class="edu.xalead.UserDao"></bean>
<bean id="userServlet" class="edu.xalead.UserServlet">
    <property name="userDao" ref="userDao"/>
</bean>

但其实我们没必要这样写,Bean中you自动注入的属性autowire,他有两个值:

  1. byName,根据名字注入,即id=“userDao”
<bean id="userDao" class="edu.xalead.UserDao"></bean>
<bean id="userServlet" class="edu.xalead.UserServlet" autowire="byName"/>
  1. byType,根据类型注入,类型注入比较有局限性,同种类型只能注入一个,多了会报不是唯一错误
<bean id="userDao" class="edu.xalead.UserDao"></bean>
<bean id="userServlet" class="edu.xalead.UserServlet" autowire="byType">

4.构造注入

<!-- User有个四参构造,我们通过constructor-arg一个一个对应构造参数进行值的注入 -->
<bean id="user" class="edu.xalead.User">
    <constructor-arg value="1111"/>
    <constructor-arg value="zhangsan"/>
    <constructor-arg value="20"/>
    <constructor-arg value="M"/>
</bean>

构造注入和set注入的不同点就是,加入元素的顺序必须和你所创建的实体(User)类相同,若不同,则会报错,由于反射过来的类型和转换器转换的类型不同,这时候我们需要加入另一个属性index

<!-- User有个四参构造,我们通过constructor-arg一个一个对应构造参数进行值的注入 -->
<bean id="user" class="edu.xalead.User">
    <constructor-arg value="M" index="3"/>
    <constructor-arg value="zhangsan" index="1"/>
    <constructor-arg value="1111"/ index="0">
    <constructor-arg value="20" index="2"/>
</bean>

那什么时候使用构造注入呢?当我们自己定义一个构造函数的时候使用构造注入

public class User {
    private int id;
    private String name;
    private int age;
    private String sex;
    private String birthday;
	//自定义构造函数
    public User(int id , String name){
        this.id = id;
        this.name = name;
    }

}
<bean id="user" class="edu.xalead.User">
        <constructor-arg value="18"/>
        <constructor-arg value="张三"/>
    </bean>

这个时候就不能使用set注入,他会报错,即使你写出全参构造函数也不行
在这里插入图片描述

5.Array注入(数组注入)

  private String[] photos;
<property name="photos">
<array>
    <value>1.jpg</value>
    <value>2.jpg</value>
    <value>3.jpg</value>
</array>
</property>

6.List注入

 private List<String> list;

<property name="list">
<list>
    <value>a</value>
    <value>b</value>
    <value>c</value>
</list>
</property>

7.Set注入

private Set<String> set;
<property name="set">
<set>
    <value>a</value>
    <value>b</value>
    <value>c</value>
</set>
</property>

8.Map注入

private Map<Integer,String> map
<property name="map">
<map>
	//第一种写法
   <entry key="1" value="a"/>
   //第二种写法
   <entry key="2">
       <value>b</value>
   </entry>
   <entry key="3" value="c"/>
   
</map>
</property>

9.Property注入

private Properties prop;
<property name="prop">
    <props>
        <prop key="4432">42341231</prop>
        <prop key="54353">5464564</prop>
        <prop key="9865">2659846</prop>
    </props>
</property>

若有误,请指教!

以上是关于Spring Bean 的基本配置的主要内容,如果未能解决你的问题,请参考以下文章

死磕 Spring----- IOC 之从单例缓存中获取单例 bean

[死磕 Spring 17/43] --- IOC 之从单例缓存中获取单例 bean

What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段

Spring装配bean--02通过Java代码装配bean

05Spring源码-手写篇-手写Bean配置

Spring二 Bean详解