Spring学习笔记
一、IoC入门
1.什么是IoC
IoC即控制反转,一个类不再主动控制创建自己所依赖的类,而是交给外部容器去控制创建自己所依赖的类。例如,有一个汽车厂,原本想要制作一辆汽车,需要自己制作发动机、轮胎、方向盘等零部件,汽车就是这个类,发动机和轮胎就是它的依赖项,这些依赖项需要汽车自己用new创建出来;使用IoC之后,这些零件就不需要汽车厂自己去制作了,都交给外部别的厂商去制作,汽车厂只需要把这些零件拼装起来。这里的外部厂商就是ApplicationContext.
2.IoC的好处
有了IoC之后,代码的耦合性就会大大降低,原本,当一个类的依赖改变时,这个类里面的源代码必须修改,因为在类内new了这个依赖,而现在不需要在类内new这个依赖,只需要修改对应的配置文件即可
3.例子
这是一个BookDao的实现类,代表一本book
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("save Book");
}
}
这是一个service的实现类,其内部依赖于BookDao去调用save方法
public class serviceImpl implements service {
private BookDao bookDao;
@Override
public void SaveBook(){
System.out.println("BookService working");
bookDao.save();
}
public void setBookDao(BookDaoImpl bookDao) {
this.bookDao = bookDao;
}
}
这是main方法
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
service service = (service) context.getBean("serviceImpl");
service.SaveBook();
}
可以看到,在main方法中,并没有调用sercice中的setBookDao()这个方法,而service类的内部也没有new一个BookDao,但代码是可以正常执行的,没有报空指针异常,这是因为ApplicationContext这个容器自动调用了set方法创建了一个BookDao的对象,并赋值给了service内部的bookDao属性。而这是通过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">
<bean id="bookDaoImpl" class="com.cexy.dao.impl.BookDaoImpl"/>
<bean id="serviceImpl" class="com.cexy.service.impl.serviceImpl">
<property name="bookDao" ref="bookDaoImpl"/>
</bean>
</beans>
可以看到这里配置了两个bean,一个是bookDaoImpl,一个是serviceImpl。配置serviceImpl的作用是在main方法中,可以不用手动new一个serviceImpl的对象,而是可以直接通过
service service = (service) context.getBean("serviceImpl");
来获取。
注意到它的bean中还有property这个标签,这是用来说明依赖关系的,即告诉编译器类中有一个依赖,类型对应ref="??"中的类型,在创建这个类时,容器会自动new出这个依赖,并通过set方法赋值给类中的属性。在示例代码中,service的依赖就是BookDao,于是通过
public void setBookDao(BookDaoImpl bookDao) {
this.bookDao = bookDao;
}
让private BookDao bookDao;有了值。但是注意,配置中property标签的属性name对应的值并不是类中属性的名字,而是set函数中传递的形参的名字,即
public void setBookDao(BookDaoImpl bookDao) {
this.bookDao = bookDao;
}
中的形参名bookDao,与类本身属性名无关。