Ioc(Inversion of Contorl)控制反转---->一种编程思想
为了降低程序的耦合性,我们由主动new一个对象转换为由外部提供对象。
此过程中对象创建控制权由程序转移到外部,这种思想叫做控制反转。
Spring技术对这种思想进行了实现。
Spring提供了一个容器,称之为“Ioc容器”充当Ioc思想中的外部。
Ioc容器负责对象的创建、初始化等一系列操作,被创建或者管理的容器在Ioc容器中成为bean。
DI(dependency Injection)依赖注入
在容器中建立bean与bean之间的依赖关系的整个过程,称之为依赖注入。
1、导入maven坐标
org.springframework
spring-context
5.2.10.RELEASE
2、创建Spring配置文件
bean标签表示配置bean
id属性表示给bean起名字
class属性表示给bean定义类型
注意:之前的new我们可以理解为自己做菜,而这里面的bean相当于告诉计算机菜单,要求计算机给你做哪些菜。同时对于bean,我们可以在不同的bean中间建立起联系。
3、获取Ioc容器
4、通过Ioc容器获取bean
public class APP2 {
public static void main(String[] args) {
//3、获取Ioc容器
ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
//4、获取bean
//此处利用了接口多态,即编辑看左,运行看右边,创建的对象实际是实现类对象,但是类型是接口(向上转换)
BookDao BookDao=(BookDao) act.getBean("BookDao_test");
//调用了子类中重写的方法,且向上转换只能调用子类重写的方法
BookDao.save();
}
}
为了将service中通过new创建dao对象的代码删除,我们需要提供在service中创建dao对象的方法。同时,我们需要在配置文件中描述service对象和dao对象之间的关系。
5、去除new
6、创建set方法提供dao对象
public class BookServiceImpl implements BookService {
//5、去除new
private BookDao bookDao;
@Override
public void save() {
System.out.println("BookServiceImpl is saving");
bookDao.save();
}
//6.提供对应的set方法
//set方法是容器在调用,谁要创建对象谁调用
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
7、配置sever与dao的关系
请注意:第一个name对应的bookDao指的是方法形参,用来对应创建对象。
第二个ref对应的bookDao指的是关联其他bean的id,(其实关联其他bean的name别名也可以起到同样的效果,但是我们一般不这样使用)。
1、bean的基础配置
格式:
属性:id:容器根据id获取对应的bean,一个容器id值唯一
class:bean的类型,即配置bean的全路径类名
2、bean的作用范围
名称:scope
功能:控制bean创建的对象是否单例(多次创建是否是同一个对象)
singleton:单列
prototypr:非单列
为什么Spring创建的对象大多都是单列的?
这是因为Spring所创建的bean主要是复用的对象,即拿一次用一次,这样才会更加节省资源。
3、bean的同名配置
名称:name
功能:定义bean的别名,可以有多个,可以用逗号,分号,空格隔开。
bean实列化的三种方法
bean的本质:bean是一个对象,创建对象通过无参数的构造方法创建。
方法一:通过可访问的无参数构造方法在实现类中创建对象
其实写不写构造方法是一样的,如果你不写虚拟机会自动提供。
无参构造方法如果不存在,将会抛出BeanCreationException。
//创建构造方法
public BookDaoImpl(){
System.out.println("book dao constructor is running");
}
方法二:静态工厂创建对象
创建工厂返回对象,可以提前做出一些配置,比如说sout
public class OrderDaoFactory {
//通过类名调用静态方法
public static OrderDao getOrderDao(){
System.out.println("factory is setting up");
//通过工厂返回方法创建一个对象
return new OrderDaoImpl();
}
}
配置文件
主页app
public class APP {
public static void main(String[] args) {
ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
//5、获取bean
//此处利用了接口多态,即编辑看左,运行看右边,创建的对象实际是实现类对象,但是类型是接口(向上转换)
OrderDao OrderDao=(OrderDao) act.getBean("orderDao");
//调用了子类中重写的方法,且向上转换只能调用子类重写的方法
OrderDao.save();
}
}
方法三:非静态工厂创建对象
public class UserFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
第一行的UserFactory实际上并没有意义,仅仅作为第二个bean的变量存在。
第二个bean中的方法名每次都不固定,所以这种方法并不实用。
方法四:方法三的改良
public class UserFactoryBean implements FactoryBean {
//代替原始实列中创建对象的方法
@Override
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
//对象的返回值是什么类型
@Override
public Class> getObjectType() {
return UserDao.class;
}
//是否为单列对象
@Override
public boolean isSingleton(){
return true;
}
}
这里的对象造出的不是FactoryBean的对象,这里造出来的是Object对象。
生命周期:从创建到销毁的完整过程
bean生命周期:bean从创建到销毁的整体过程
bean生命周期控制:bean创建后到销毁前做的一些事情