这里我就不过多描述spring的发展历史之类的了,咱们直接进入正题。(有想了解的可以自行度娘)
一、Spring核心概念
IOC(Inversion Of Control)控制反转
这里的反转并不是指电视剧中的情节反转,而是对于对象的创建控制权由内部创建(程序员自行创建)反转为了外部创建(Spring提供创建)。简单来讲,就是将new对象的权利交给了Spring,我们只需要从Spring中获取对象。
IOC容器思想
Spring提供了容器我们称为IOC容器,就是当作IOC思想中的“外部”
IOC容器负责对对象的创建、初始化和销毁等一系列工作,被管理的对象在IOC容器中统称为Bean
DI(Dependency Injection)依赖注入
在容器中建立Bean之间的依赖关系的整个过程,被成为依赖注入
例如,我们可以在Service层实现类创建Dao层实现类的变量,但是不进行赋值,后在spring配置文件中对其进行依赖注入,代码如下:
BookServiceImpl.java
public class BookServiceImpl implements BookService {
private BookDao bookDao;
//在进行依赖注入时需要入口,setter入口是其中一种
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
//BookDao的实现类中已经重写了save()方法
bookDao.save();
}
}
Application.xml
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<!--对bookService进行依赖注入,将bookDaoBean注入到BookServiceImpl中的变量中,此时就产生了依赖关系-->
<property name="bookDao" ref="bookDao"></property>
</bean>
SpringTest.java
public class SpringTest{
public static void main(String[] args) {
//1.获取spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
//2.通过容器获取bookService实例对象
BookService bookService = (BookService) context.getBean("bookService");
//3.调用实例对象方法
bookService.save();
}
}
我们并没有在BookServiceImpl中创建BookDao的实例对象,但是save()方法依然被调用成功了。因为spring 在容器创建时就将BookDao实现类的实例对象通过依赖关系注入到了BookServiceImpl中的变量中。
二、Bean
1、Bean的属性介绍
bean标签
id:唯一标识,
class:这个bean绑定的类(把哪个类交给spring来处理),包名+类名
name:别名,可以起多个别名(用空格隔开)
scope:作用范围
singleton:单例(默认)
单例情况下该对象由Spring全权管理,由Spring进行创建、销毁,每次都是同一个对象
prototype:非单例
非单例情况下该对象由Spring创建,每次都是新对象,创建后就不再和对象有关系了
scope的取值不只有这两种,只是这两种较为常用。还有request、session、application、websocket,表示创建出的对象存放web容器(tomcat)中的位置。比如,request表示保存到request域中。
2、Bean的实例化
Bean的实例化方式可以分为四种,如下:
<!--方式一:构造方法实例化bean-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
<!--方式二:使用静态工厂实例化bean-->
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory"
factory-method="getOrderDao"></bean>
<!--方式三:使用实例工厂实例化bean-->
<bean id="userDaoFactory" class="com.itheima.factory.UserDaoFactory"></bean>
<bean id="userDao" factory-bean="userDaoFactory" factory-method="getUserDao"></bean>
<!--方式四:使用FactoryBean实例化bean-->
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"></bean>
1).构造方法实例化
这种方式是bean的最基础的实例化方式,此时绑定的类中需要有空参构造,否则会报错。它是基于构造完成的,底层采用反射技术,默认空参构造创建对象。
2).静态工厂实例化
以前我们需要调用工厂类的静态方法来获取对象,现在可以直接全权交给Spring来进行管理,直接调用静态工厂Bean对应id就可以获取到实例,class绑定工厂类,factory-method就是获取实例对象的方法。当我们通过静态方法多次调用时产生的是多个新的对象,但是通过spring进行管理后我们多次调用也只是获得同一个对象。
3).实例工厂实例化
实例工厂就需要创建工厂对象后才能调用获取实例的方法,同理,在spring中我们也需要创建实例工厂的Bean,创建后我们在获取实例的Bean中通过factory-bean绑定实例工厂。
4).工厂类实现FactoryBean后实例化
实现FactoryBean的工厂类,如下:
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
public Class<?> getObjectType() {
return UserDao.class;
}
}
实现FactoryBean后方法就固定了,FactoryBean范性中只需要写入需要实例化的类的接口类型就可以,然后直接绑定Bean的class属性就可以使用了。
3、Bean的生命周期
默认情况下,对象是单例模式:
springIOC容器创建的时候,就完成了对象的创建和初始化管理
SpringIOC容器关闭的时候,就会执行对象的销毁
如果对象是非单例的情况:
SpringIOC容器创建的时候,不会进行对象的创建和初始化
当你需要时,getBean才会去创建对象,而且每次调用getBean获取到的都是新对象
SpringIOC容器与这些对象不再有联系,所以在容器销毁时这些对象并不会销毁
三、依赖注入
依赖注入---就是给类中的成员属性赋值
1.set注入方式
简单(基本类型+String)类型的set注入(直接通过value属性就可以实现注入)
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<property name="Name" value="mysql"/><!--String类型-->
<property name="Num" value="5"/><!--int类型-->
</bean>
引用类型的依赖注入(创建引用类型的bean后,通过ref实现注入)
<!--bookDao的Bean在上面-->
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
<property name="userDao" ref="userDao"/>
</bean>
2.构造注入方式(一般用不到,源码中大部分用构造)
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg name="Name" value="mysql"/>
<constructor-arg name="Num" value="5"/>
</bean>
通过有参构造生成Bean,constructor-arg的个数要和对应的有参构造方法的个数相同,name属性要和有参构造的行参名相同,中间顺序没有要求,基本类型用value注入,引用类型用ref注入。
3.自动装配
当我们对引用类型进行依赖注入时,我们就可以使用自动装配(自动依赖注入)。
<bean class="com.itheima.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="service" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"></bean>
自动装配就是构建对象后检查属性,自动去Spring中找对应类型的Bean,如果有就进行注入。
autowire="byType" 按照类型自动装配
autowire="byName" 按照id注入,要求id属性 和 set方法去set后的名字一致
4.set注入特殊类型(了解)
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<!--数组类型-->
<property name="array">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
<!--List集合类型-->
<property name="list">
<list>
<value>贾乃亮</value>
<value>王宝强</value>
<value>陈羽凡</value>
</list>
</property>
<!--Set集合类型-->
<property name="set">
<set>
<value>a</value>
<value>s</value>
<value>d</value>
</set>
</property>
<!--Map集合类型-->
<property name="map">
<map>
<entry key="1" value="蔡徐坤"/>
<entry key="2" value="李诞"/>
<entry key="3" value="李丹"/>
</map>
</property>
<!--Properties键值对类型-->
<property name="properties">
<props>
<prop key="4">胡歌</prop>
<prop key="5">彭于晏</prop>
<prop key="6">甄子丹</prop>
</props>
</property>
</bean>
简单类型用value 引用类型用ref(如:key-ref)。
Spring相关的知识还是挺多挺杂的,基础先写这么多,后续还会有更新。。。。。