目录
简单类型set注入(使用value):spring调用类的set方法,通过set方法完成属性赋值
1.Spring框架使用DI实现IoC
通过spring框架,只需要提供要使用的对象名词就可以了。从容器中获取名称对应的对象。
Spring底层使用的 反射机制,通过反射创建对象给属性。
tomcat也是容器:管理的是servlet,listener,filter等对象
2.Spring的配置问文件
Spring标准的配置文件:
(1)根标签是beans
(2)beans后面是约束文件说明
(3)beans里面是bean声明
(4)什么是bean?bean就是java对象,spring容器管理的java对象,叫做bean
bean中声明对象
<bean id ="" class=" "/>
id 为对象的名称,唯一值(可以没有,Spring提供默认的名称)
class 类的全限定名称
Spring根据id、class创建对象,把对象放入spring的一个map对象,map.put(id,对象)
我们之前创建对象用的是无参构造,现在Spring默认调用无参构造方法,如果定义了有参数构造,应该再定义无参数构造方法。
Spring在什么时候创建对象?
创建spring容器对象的时候,会读取配置文件,创建文件中声明的java对象。
优点:获取对象速度快,因为对象已经创建好了
缺点:比较占用内存
Spring创建对象一次创建几个?
在创建容器(ApplicationContext)对象时,对把配置文件中的所有对象创建出来(Spring的默认规则)
获取bean对象个数,以及对象名字,可以通过方法来获得
3.Spring创建非自定义对象
非自定义对象,也就是不是我写的类
<bean id="mydate" class="java.util.Data"/>
4.Spring创建没有接口的对象
<bean id="myStudent" class="com.wangqi.ioc2.项目.ba02.Student"> <property name="name" value="王淇"/> <!-- setName("王淇")--> <property name="age" value="18" /> <!-- setAge(22)--> </bean>
5.DI:给属性赋值
spring调用类的无参构造,创建对象,对象创建后给属性赋值
给属性赋值可以使用:(1)xml配置文件中的标签和属性 (2)使用注解
DI分类:1.set注入 2.构造注入
3.1基于xml的DI
在xml配置文件中使用标签和属性,完成对象的创建,属性赋值
3.2set注入,也叫做设值注入
spring调用类中的set方法,在set方法中完成属性赋值,推荐使用
简单类型set注入(使用value):spring调用类的set方法,通过set方法完成属性赋值
简单类型为java中的基本数据类型
语法:<bean id="XXX" class="yyy">
<property name="属性名" value="简单属性类型值"/>
. .......
</bean>
不管属性是什么,都要加""
Spring要给属性赋值,必须有对应的set方法
给属性赋值看的是有没有set方法,与有没有属性无关,与属性名无关
<bean id="myStudent" class="com.wangqi.ioc2.项目.Student"> <property name="name" value="王淇"/> <property name="age" value="18" /> </bean>
public class Student { 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; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
@Test public void test04(){ String config="spring-config.xml"; ApplicationContext ctx =new ClassPathXmlApplicationContext(config); Student student =(Student)ctx.getBean("myStudent"); System.out.println("student="+student); }
非自定义类属性赋值
找到这个类的set方法
<bean id="date" class="java.util.Date"> <property name="time" value="295349276"/> <!--对应Date类的settime--> </bean>
Date date=(Date)ctx.getBean("date"); System.out.println(date);
引用类型set注入:
语法格式:<bean id="XXX" class="yyy">
<property name="属性名" ref="bean的id"/>
.........
</bean>
<bean id="myStudent" class="com.wangqi.ioc2.项目.ba02.Student"> <property name="name" value="王淇"/> <property name="age" value="18" /> <!--引用类型的数据赋值 --> <property name="school" ref="mySchool"/><!--setSchool(mySchool)--> </bean> <!--声明School --> <bean id="mySchool" class="com.wangqi.ioc2.项目.ba02.School"> <property name="name" value="北京大学"/> </bean>
public class School { private String name; private String address; public void setName(String name) { this.name = name; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }
public class Student { private String name; private int age; //声明一个引用类型 private School school; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setSchool(School school) { System.out.println("school="+school); this.school = school; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
@Test public void test05(){ String config= "ba02/applicationContext.xml"; ApplicationContext ctx =new ClassPathXmlApplicationContext(config); //myStudent区分大小写 Student student =(Student)ctx.getBean("myStudent"); System.out.println("student="+student); }
(2)构造注入
构造注入:spring调用类中的有参数构造方法,在创建对象的同时,给属性赋值
语法:<bean id="XXX" class="yyy">
<constructor-arg:表示一个构造方法的形参
标签有属性:name:构造方法形参名
index:构造方法的参数位置
value:简单类型的形参值
ref:引用类型的形参值
</bean>
使用name属性
<!--构造注入使用name属性 --> <bean id="myStudent" class="com.wangqi.ioc2.项目.ba03.Student"> <!-- 对应的是形参名,不是属性名--> <constructor-arg name="myname" value="李四"/> <constructor-arg name="myage" value="20"/> <constructor-arg name="mySchool" ref="mySchool"/> </bean>
<!--声明School --> <bean id="mySchool" class="com.wangqi.ioc2.项目.ba03.School"> <property name="name" value="北京大学"/> <property name="address" value="北京的海淀区"/> </bean>
使用index属性
省略index属性
也可以没有问题
创建file对象
<!--声明File对象--> <bean id="myFile" class="java.io.File"> <constructor-arg name="parent" value="D:\\1"/> <constructor-arg name="child" value="message.txt"/> </bean>
//获取file对象 File file=(File)ctx.getBean("myFile"); System.out.println("file="+file);
(3)引用类型的自动注入
spring可以根据某些规则给引用类型完成赋值。只对引用类型有效
常用的两个规则:byName、byType
byName(按名称注入)
java类中引用类型属性名称和spring容器中的bean的id是一样的,且数据类型也是一样的,这些bean能够赋值给引用类型。
语法格式:
<bean id="XXX" class="yy" autowire="byName">
简单类型属性赋值
</bean>
<!--byName 自动注入--> <bean id="myStudent" class="com.wangqi.ioc2.项目.ba04.Student" autowire="byName"> <property name="name" value="王淇"/> <property name="age" value="18" /> <!--引用类型的数据赋值 --> <!-- <property name="school" ref="mySchool"/><!–setSchool(mySchool)–>--> </bean> <!--声明School --> <bean id="school" class="com.wangqi.ioc2.项目.ba04.School"> <property name="name" value="清华大学"/> <property name="address" value="北京的海淀区"/> </bean>
public class Student { private String name; private int age; //声明一个引用类型 private School school; public Student(){ System.out.println("Student类的无参构造方法"); } public Student(String myname, int myage, School mySchool){ System.out.println("Student类的有参构造方法"); //给属性赋值 this.name=myname; this.age=myage; this.school=mySchool; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } public void setName(String name) { this.name=name; } public void setAge(int age) { this.age = age; } public void setSchool(School school) { this.school = school; } }
byType(按类型注入)
java类中引用数据类型和spring容器中bean的class值是同源关系,这样的bean赋值给引用类型。
同源类型:
1.java中引用类型的数据类型和bean的class值是一样的
2.java中引用类型的数据类型和bean的class值是父子类关系的
3.java中引用类型的数据类型和bean是接口和实现类的关系
语法格式:
<bean id="XXX" class="yy" autowire="byType">
简单类型属性赋值
</bean>
在xml配置文件中,符合条件的对象,只能有一个,多余的一个是报错的
<!--byType 自动注入--> <bean id="myStudent" class="com.wangqi.ioc2.项目.ba05.Student" autowire="byType"> <property name="name" value="张三"/> <property name="age" value="26" /> </bean> <!--声明School --> <!-- <bean id="school2" class="com.wangqi.ioc2.项目.ba05.School">--> <!-- <property name="name" value="航空大学"/>--> <!-- <property name="address" value="北京的海淀区"/>--> <!-- </bean>--> <bean id="primary" class="com.wangqi.ioc2.项目.ba05.PrimarySchool"> <property name="name" value="北京大兴小学"/> <property name="address" value="北京大兴区"/> </bean>
6.项目中Spring多个配置文件
分多个配置文件:
(1)按功能模块分,一个模块一个配置文件
(2)按类的功能分,数据库操作相关的类在一个文件,service在一个配置文件,配置redis,事务等等一个配置文件。
spring管理多个配置文件:常用的是包含关系的配置文件,项目中有一个总的文件,里面是有import标签包含其他的多个配置文件。
语法:
总的文件(xml)
<import resourse="其他的文件的路径1"/>
<import resourse="其他的文件的路径2"/>
关键字"classpath":表示类路径,也就是类文件(class文件)所在的目录。spring到类路径中加载文件。
什么时候使用classpath:在一个文件中使用其他的文件,需要classpath。
多配置文件的应用
下面是两个配置文件:学生模块一个配置文件,学校模块一个配置文件
方法一:
<!-- 当前是总的配置文件,目的是包含其他的多个配置文件,一般不声明bean 语法: <import resource="classpath:"其他文件的路径"/> classpath:表示类路径。类所在的目录,spring通过类路径加载配置文件 --> <import resource="classpath:ba07/spring-school.xml"/> <import resource="classpath:ba07/spring-student.xml"/>
方法二:使用通配符
<!--包含关系的配置文件,可使用通配符* :表示任意字符--> <import resource="classpath:ba07/spring-*.xml"/>
注意:总的文件名称,不能包含在通配符范围内(application.xml)不能叫做spring-applicationContext.xml