spring对象的获取及属性赋值方式 :
其中,(见上)
1、通过bean的id获取IOC容器中的对象(上面已经用过)
2、通过bean的类型来获取对象
注意:当通过类型进行获取的时候,如果存在两个想同类型的对象,将无法完成获取工作
如在ioc.xml配置文件中,再创建一个person2:
如果此时,测试类中还是如下方式进行获取:
Person person = context.getbean(Person.class);
则,运行时会报错。
想要获取相同类型的不同对象,在测试类进行获取的时候需要采取 id + 类型 的方式:
获取方式:id —— 是比较准确的
type/类型 —— 也可以,但是用这种方式不能包含两个相同类型的对象
( id + 类型)
还有其他方式,见上,但是用的比较少。常用的还是前面3种。
(插注:Spring IOC 容器底层用的实现技术是反射)
3、通过构造器给bean对象赋值
当需要从容器中获取对象的时候, 最好要保留无参构造方法,因为底层的实现是反射。
如果用带参数的构造函数,则要换另外一种方式(即ioc.xml配置文件要进行如下配置):
见代码。
代码示例:
Person类:
package com.zhoulz.bean;
/**
* @Auther: zhoulz
* @Description: com.zhoulz.bean
* @version: 1.0
*/
public class Person {
private int id;
private String name;
private Integer age;
private String gender;
public Person() {
System.out.println("person被创建了!");
}
public Person(int id, String name, Integer age, String gender) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
// 同是3个参数的构造方法,但是类型不一样
public Person(int id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
System.out.println("age--------"); //用来作区分的
}
public Person(int id, String name, String gender) {
this.id = id;
this.name = name;
this.gender = gender;
System.out.println("gender------");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
ioc.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--另注:
在进行框架配置的时候,可以使用xml文件,也可以使用注解的方式
虽然像有些人觉得xml的方式比较麻烦,但是(但是很重要!!!)xml的配置方式还是要学习的,因为在项目的开发过程中
很多情况下是xml和注解一起工作,而且xm配置的方式比较完整
-->
<!--对应不带参数的(即无参)构造函数-->
<!--根据属性值设置的时候,name的名称取决于set方法后面参数首字符小写的名称-->
<!--
name:表示参数列表的名称;
value:表示参数列表的具体指;
type:表示实际的具体值;
index:表示值的下标,从0开始。
-->
<!--bean id="person" class="com.zhoulz.bean.Person" scope="prototype"--> <!--多例-->
<bean id="person" class="com.zhoulz.bean.Person" > <!--单例-->
<property name="id" value="1"></property>
<property name="name" value="lisi"></property>
<property name="age" value="20"></property>
<property name="gender" value="男"></property>
</bean>
<!--当通过类型进行获取的时候,如果存在两个相同类型的对象,将无法完成获取工作-->
<!--//再创建一个 —— 和上面是两个相同类型的对象 —— 不行
<bean id="person2" class="com.zhoulz.bean.Person" >
<property name="id" value="12"></property>
<property name="name" value="lisi2"></property>
<property name="age" value="22"></property>
<property name="gender" value="女"></property>
</bean>-->
<!--对应带参数的构造函数-->
<!--使用构造器方法赋值的时候,参数的name属性是由什么来决定的?由构造方法的参数名称决定的-->
<!--<bean id="person2" class="com.zhoulz.bean.Person">
<constructor-arg name="id" value="2"></constructor-arg>
<constructor-arg name="name" value="lisi3"></constructor-arg>
<constructor-arg name="age" value="22"></constructor-arg>
<constructor-arg name="gender" value="男"></constructor-arg>
</bean>-->
<!--上面方法的简便写法:—— 去掉 name="***"-->
<!--当通过构造方法赋值的时候,可以把name属性值省略不写,但是要注意必须保证参数值
跟构造器的参数列表的顺序一致(否则会乱序)-->
<bean id="person3" class="com.zhoulz.bean.Person">
<!--<constructor-arg value="2"></constructor-arg>
<constructor-arg value="lisi3"></constructor-arg>
<constructor-arg value="22"></constructor-arg>
<constructor-arg value="男"></constructor-arg>-->
<!--不一致也可以,但是得加上index参数(参数值从0开始(这里为0-3),如:-->
<constructor-arg value="2"></constructor-arg>
<constructor-arg value="男" index="3"></constructor-arg>
<constructor-arg value="22"></constructor-arg>
<constructor-arg value="lisi3" index="1"></constructor-arg>
</bean>
<!--有两个同是3个参数的构造方法,但是类型不一样-->
<!--问:“24” 会赋给gender还是age?这里是gender,因为gender在后面(覆盖)
即:当有多个相同参数的构造方法存在的时候,默认情况下是覆盖的过程,后面的构造方法会覆盖前面的构造方法
如果非要赋值给另一个构造方法的话(如这里,想把24赋给age怎么办?)
:可以使用type的参数进行指定-->
<bean id="person4" class="com.zhoulz.bean.Person">
<constructor-arg value="4"></constructor-arg>
<constructor-arg value="wangwu"></constructor-arg>
<!--<constructor-arg value="24"></constructor-arg>-->
<constructor-arg value="24" type="java.lang.Integer"></constructor-arg>
</bean>
<!--总结:
在日常的工作中,一般都是使用name,value的方式,很少有人去使用index或者type的方式
但是要注意各种情况出现的问题
-->
</beans>
测试类:MyTest 2
import com.zhoulz.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Auther: zhoulz
* @Description: PACKAGE_NAME
* @version: 1.0
*/
public class MyTest2 {
public static void main(String[] args) {
ApplicationContext context2 = new ClassPathXmlApplicationContext("ioc.xml");
//通过bean的标签的id来获取对象
//Person person3 = context2.getBean("person", Person.class);
//System.out.println(person3);
//通过bean的类型来获取对象
//注意:当通过类型进行获取的时候,如果存在两个相同类型的对象,将无法完成获取工作
/*Person bean = context2.getBean(Person.class);
System.out.println(bean);*/
/*
* 当需要从容器中获取对象的时候, 最好要保留无参构造方法,因为底层的实现是反射
*
* Class class = Person.class;
* Object obj = class.newInstance();//默认调用无参的构造方法,已弃用.
* 上面的方法已经被弃用了,现在用的是:
* Object obj = class.getDeclaredConstructor().newInstance();
* */
//对应——带参数的构造函数
//Person person4 = context2.getBean("person2",Person.class);
Person person4 = context2.getBean("person4",Person.class);
System.out.println(person4);
}
}