这是看颜群老师的Spring教程后整理的笔记
Ⅰ、为什么要引入IOC容器
-
传统的创建对象的方式
Object obj = new Object(); obj.setAAA(...); obj.setBBB(...); obj.setCCC(...); obj.getAAA();
如果对象的某个属性名称需要修改,例如AAA属性名字改为aaa,那么就需要修改所有关于AAA属性的代码。如果用到setAAA的代码很多,就需要修改很多次,改成很多个setaaa...
-
IOC方式
- 写xml配置文件:把对象放在IOC容器里并赋值
- 从容器里面拿这个对象
IOC(控制反转)也可以称之为DI(依赖注入)
Ⅱ、怎么用SpringIOC
1.把对象放入IOC容器
<bean id="student" class="org.lanqiao.entity.Student">
<property name="stuNo" value="2"></property>
<property name="stuName" value="ls"></property>
<property name="stuAge" value="24"></property>
</bean>
- property:该class所代表的类的属性
- name:属性名
- value:属性值
- id:对象的唯一标识符,Java代码通过id来取对象
实际上,这段xml中赋值的部分是调用了Student类中的set方法来完成的
注意:在ioc中定义bean的前提是该bean的类必须提供了无参构造
2.从IOC容器中获取对象并使用
ApplicationContext conext = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student)conext.getBean("student");//通过id值获取,注意需要类型转换
...
Ⅲ、依赖注入的三种方式
1.set注入:通过setXxx()赋值
使用set方法进行赋值
上面采用的<property...>就是set注入
依赖注入的底层是通过反射实现的
2.构造器注入:通过构造方法赋值
假设构造方法的定义:
Student(String name, int age){
this.name=name;
this.age=age;
}
①按照构造方法的参数对应的顺序赋值
<bean...>
<constructor-arg value="ls"></constructor-arg>
<constructor-arg value="24"></constructor-arg>
</bean>
②按照参数类型赋值
<bean...>
<constructor-arg value="24" type="int"></constructor-arg>
<constructor-arg value="ls" type="String"></constructor-arg>
</bean>
③按照构造方法的参数的索引赋值
<bean...>
<constructor-arg value="24" index="1"></constructor-arg>
<constructor-arg value="ls" index="0"></constructor-arg>
</bean>
④按照属性的名称赋值
<bean...>
<constructor-arg value="24" name="age"></constructor-arg>
<constructor-arg value="ls" name="name"></constructor-arg>
</bean>
总结:后三种都不用遵循构造器参数列表的顺序
3.p命名空间注入
首先需要在applicationContext.xml中引入p命名空间
xmlns:p="http://www.springframework.org/schema/p"
简单类型:p:属性名="属性值"
引用类型(除了String外):p:属性名-ref="引用的id"
注意:多个p赋值的时候要有空格
例如:
<bean id="course" class="org.lanqiao.entity.Course" p:courseHour="300" p:courseName="hadoop" p:teacher-ref="teacher">
前两个属性很简单,最后一个是赋值了一个teacher对象作为属性值
Ⅳ、依赖注入的特殊情况
1.注入各种集合数据类型
①注入链表:
<property name="listElement">
<list>
<value>足球</value>
<value>篮球</value>
<value>乒乓球</value>
</list>
</property>
②注入数组
<property name="arrayElement">
<array>
<value>足球1</value>
<value>篮球1</value>
<value>乒乓球1</value>
</array>
</property>
③注入set
<property name="setElement">
<set>
<value>足球2</value>
<value>篮球1</value>
<value>乒乓球2</value>
</set>
</property>
④注入map
<property name="mapElement">
<map>
<entry>
<key>
<value>foot</value>
</key>
<value>足球3</value>
</entry>
<entry>
<key>
<value>basket</value>
</key>
<value>篮球3</value>
</entry>
</map>
</property>
- entry表示一个键值对
⑤注入properties
<property name="propsElement">
<props>
<prop key="foot4">足球4</prop>
<prop key="basket4">篮球4</prop>
<prop key="pp4">乒乓球4</prop>
</props>
</property>
2.给对象赋值null或""(空字符串)
- null
<property name="name" >
<null/> <!--注意 没有<value>-->
</property>
- ""
<property name="name" >
<value></value>
</property>
Ⅴ、自动装配
自动给一个类中的属性类初始化并赋值
<bean ... class="org.lanqiao.entity.Course" autowire="byName|byType|constructor|no" >
- byName: 自动寻找其他bean的id值=该Course类的属性名(本质上是byId)
- byType: 其他bean的类型(class)是否与 该Course类的ref属性类型一致(注意,此种方式必须满足:当前Ioc容器中 只能有一个Bean满足条件)
- constructor:其他bean的类型(class)是否与该Course类的构造方法参数的类型一致。此种方式的本质就是byType
可以在头文件中一次性将该ioc容器的所有bean统一设置成自动装配:
<beans xmlns="http://www.springframework.org/schema/beans"
...
default-autowire="byName">
注意:自动装配虽然可以减少代码量,但是会降低程序的可读性,使用时需要谨慎。
Ⅵ、使用注解定义bean
通过注解的形式将bean以及相应的属性值放入ioc容器
1.扫描器
<context:component-scan base-package="org.lanqiao.dao">
</context:component-scan>
Spring在启动的时候,会根据base-package在该包中扫描所有类,查找这些类是否有注解@Component("studentDao"),如果有,则将该类加入spring Ioc容器。
2.注解
- @Component:使一个类成为bean
- @Repository:dao层注解
- @Service:service层注解
- @Controller:控制器层注解
用法:
@Repository
public class StudentDaoImpl {...}