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方法调用就会创建实例