关于Spring中xml文件中的一些小细节

1、constructor-arg

1.1、type属性

	<bean id="stu" class="com.etoak.Student">
        //constuctor-arg如果设置了type属性,会根据类型来找到相应的形参
        <constructor-arg type="int">
            <value>18</value>
        </constructor-arg>
        <constructor-arg>
            <value>gt</value>
        </constructor-arg>
    </bean>
//Student类
public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
//Test类
public class Test {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        Student stu = context.getBean("stu", Student.class);
        System.out.println(stu);//Student{name='gt', age=18}
    }
}

如果不设置type属性,则会报错,
在这里插入图片描述
说明如果type不设置默认为String类型

1.2、index属性

index代表注入的顺序,从下标0开始,形参若类型一样,可以控制index来注入顺序,若不一样,则必须要保证注入的数据类型和形参类型一样,否则会报错

<bean id="stu" class="com.etoak.Student">
        <constructor-arg index="1">
            <value>18</value>
        </constructor-arg>
        <constructor-arg index="2">
            <value>1</value>
        </constructor-arg>
        <constructor-arg>
            <value>gt</value>
        </constructor-arg>
</bean>
public Student(String name, String age, int id) {
        this.name = name;
        this.age = age;
        this.id=id;
}
//Test类
public class Test {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        Student stu = context.getBean("stu", Student.class);
        System.out.println(stu);//Student{name='gt', age='18', id=1}
    }
}

2、property

2.1、name、value属性

name:必须再Student类中包含字段为age的setter方法,否则会报错
value:值

<bean id="stu" class="com.etoak.Student">
        <property name="age" value="18"></property>
</bean>

2.2、name、ref属性

name:同上
ref:引用bean的id值

<bean id="stu" class="com.etoak.Student">
        <property name="test" ref="test"></property>
</bean>
<bean id="test" class="com.etoak.Test"></bean>

3、value标签

< value> : 可以通过value为主体注入简单数据类型。可以指定String与基本类型+基本类型的包装类型。容器在注入的时候会做适当的转换工作,这个是最底层元素,无法再嵌套别的元素了

4、ref标签

<bean id="stu" class="com.etoak.Student">
        <property name="test">
        	//bean属性的值会在容器里寻找名为test的bean对象
            <ref bean="test"></ref>
        </property>
    </bean>
<bean id="test" class="com.etoak.Test"></bean>

可以简化上述写法

<bean id="stu" class="com.etoak.Student">
        <property name="test" ref="test"/>
    </bean>
<bean id="test" class="com.etoak.Test"></bean>

5、list标签

一个bean对象的属性可以为List列表,既可以赋值,也可以注入依赖

<bean id="stu" class="com.etoak.Student">
        <property name="list">
            <list>
                <value>123</value>
                <ref bean="str"></ref>
                <value>etoak</value>
            </list>
        </property>
    </bean>
    <bean id="str" class="java.lang.String">
        <constructor-arg value="str"></constructor-arg>
</bean>

测试

public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        Student stu = context.getBean("stu", Student.class);
        System.out.println(stu.getList());//[123, str, etoak]
    }
}

6、map标签

Student类里创建一个map集合,这里给map集合注入依赖

<bean id="stu" class="com.etoak.Student">
        <property name="map">
            <map>
                <entry key="str1">
                    <value>1</value>
                </entry>
                <entry key-ref="str">
                    <value>2</value>
                </entry>
                <entry key="str3" value="1"></entry>
                <entry key-ref="str" value-ref="str"></entry>
                <entry key="str4" value-type="java.lang.Integer" value="1">
                </entry>
            </map>
        </property>
    </bean>
    <bean id="str" class="java.lang.String">
        <constructor-arg value="str2"></constructor-arg>
</bean>

测试

public class Test {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        Student stu = context.getBean("stu", Student.class);
        System.out.println(stu.getMap());//{str1=1, str2=str2, str3=1, str4=1}
    }
}

我们在这会发现map标签里面必须有entry标签,而entry标签有五个属性
key:键
value:值
这两个属性我们可以了解就是给map集合添加键值对,
key-ref:根据属性的值再容器找bean对象,则键就是该bean对象的实例
value-ref:根据该属性的值在容器找bean对象,则值就是bean对象的实例
value-type:规定value的值的类型
此外,我们可以看到上面的有两个键值重复,进行覆盖,符合map集合的语法,后添加会覆盖之前的值。

//上述map和entry标签可以改为props和prop
<bean id="stu" class="com.etoak.Student">
        <property name="map">
            <props>
                <prop key="str">1</prop>
            </props>
        </property>
</bean>

6、bean标签

6.1、scope属性

值为prototype,表示每次getBean得到对象的实例都会重新建一个

<bean id="str" class="java.lang.String" scope="prototype">
        <constructor-arg value="str2"></constructor-arg>
    </bean>

两个String对象地址不同

public class Test {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        String stu = context.getBean("str", String.class);
        String stu1 = context.getBean("str", String.class);
        System.out.println(stu==stu1);//false
    }
}

值为prototype,表示每次getBean得到对象的实例都是同一个

<bean id="str" class="java.lang.String" scope="singleton">
        <constructor-arg value="str2"></constructor-arg>
    </bean>
public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        String stu = context.getBean("str", String.class);
        String stu1 = context.getBean("str", String.class);
        System.out.println(stu==stu1);//true
    }

6.2、lazy-init属性

默认为fasle,不进行懒加载

<bean id="stu" class="com.etoak.Student" lazy-init="false"></bean>
<bean id="stu1" class="com.etoak.Student" lazy-init="default"></bean>
public class Student {
    public Student(){
        System.out.println("Student无参构造方法");
    }
    ..
}
//Test类
public class Test {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        Student stu = context.getBean("stu", Student.class);
    }
}

我们发现控制台打印两遍
在这里插入图片描述
而当他们都改为true时

<bean id="stu" class="com.etoak.Student" lazy-init="true"></bean>
<bean id="stu1" class="com.etoak.Student" lazy-init="true"></bean>
public class Test {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        //Student stu = context.getBean("stu", Student.class);
    }
}

此时控制台无任何打印,当把此注释取消掉会发现在控制台打印一行
在这里插入图片描述
当懒加载的bean对象,被getBean方法调用就会创建实例

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值