1.IOC
1.1IOC底层原理
xml 解析、工厂模式、反射
1.2IOC容器
Spring 提供 两种IOC 容器:(两个接口)
- BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
- ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
可以通过容器获取该容器内的所有bean
1.3容器内bean的创建与注入
1.3.1创建
即new一个对象,只不过是在容器里面new,且new的方式不同。
- 以xml为容器:
- 使用
<bean>
标签创建对象。id自己设置,为该对象的唯一标识(id≠对象名);类型自己设置 - 扫描带@Component类型注解的类,id为类名首字母小写,类型即为该类
- 以配置类为容器:
- 使用@Bean注解标在方法名上,id为方法名;类型为方法返回值
- 扫描带@Component类型注解的类,id为类名首字母小写,类型即为该类
创建时只能创建实现类不能创建接口,注入时即可注入进实现类也可注入进接口。就是容器里的bean只能是类不能是接口,但bean中的属性可以是类也可以是接口
1.3.2注入
注入是实现IOC的一种方式,即为容器中的对象的属性赋值
- 以xml为容器:
- 在
<bean>
标签中注入:set注入、构造器注入、自动注入 - 在被扫描的类中注入:使用@Value注解标在一个属性上
- 以配置类为容器:
- 在@Bean方法中注入:在方法体内给方法返回值赋值
- 在被扫描的类中注入:使用@Value注解标在一个属性上
只有容器中的bean才能被注入,若要注入对象类型属性则只能将容器中有的bean注入。
1.4细节
现有以下场景:
- 定义一个Parent类,再定义Son1和Son2去继承Parent类。
- 在容器中同时创建这三个类
1.4.1关于getBean()方法
- 使用容器.getBean(?.class)方法通过类型获取容器中的Bean
使用.getBean(?.class)方法时,容器会检索自己拥有的所有bean,若一个bean的类型能够赋值给?.class类型,则该bean可以作为getBean()方法的返回值返回。若有多个满足要求的Bean则抛NoUniqueBeanDefinitionException
- 若用getBean(Son1.class),则容器对所有bean检查后发现只有Son1能赋值给Son1类型,返回Son1;
- 若用getBean(Parent.class),则容器对所有bean检查后发现有Parent、Son1、Son2三个bean能赋值给Parent类型,报错
1.42关于自动注入
- 定义一个类A,A中有属性:
@Autowire
Parent parent;
@Autowire
Son1 s1;
@Autowire
Son s2;
- 将A放入容器中
对Property属性使用自动注入时,就相当这么一行代码:
Property P=容器.getBean(Property.class)
,所以当容器中有一个可以赋值给Property.class类型的bean时,会将该bean赋值给P;当有多个符合的bean则会报错;当没有符合条件的bean则也会报错(除非将注解的nullable属性设置为true)
- 若对
Parent parent;
自动注入,则会报NoUniqueBeanDefinitionException,因为容器中有Parent、Son1、Son2三个bean能赋值给Parent类型 - 若对
Son1 s1;
自动注入,则能将容器中Son1类型的bean注入给s1,因为容器中只有一个Son1类型的bean符合条件
对于getBean()方法和自动注入的原则可以这样简单记忆:
- 若容器中有一个能赋值给所需类型的bean则返回/注入该bean
- 若容器中有多个能赋值给所需类型的bean则报NoUniqueBeanDefinitionException
- 若容器种没有能赋值给所需类型的bean则报NoSuchBeanDefinitionException
- 其中所需类型的bean是指:getBean方法的.class类型参数/标注了自动注入注解的属性的类型
1.4.3FactoryBean
Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)
- 普通 bean:在配置文件中定义 bean 类型就是返回类型
- 工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样
- 创建类,让这个类作为工厂 bean,实现接口 FactoryBean
- 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
1.5容器概念模型
写代码和读代码时先整理出概念模型
2.使用
- 创建spring配置文件/类,创建对象。
- 使用CPXAC/ACAC载入xml/.class来创建ApplicationContext对象
- 使用ApplicationContext对象的getBean方法获取对象
3.AOP
切面编程有三种实现方式:
- 用spring自带的切面
创建一个类实现ApplicationContext,来完成对执行切点之前的操作;创建一个类实现AfterReturningAdvice 接口,来完成对执行切点之后的操作。再在xml中配置。
- 自定义切面
创建一个类,写两个方法,一个方法完成执行切点之前的操作,另一个完成执行切点之后的操作。再在xml中配置。
- 注解切面
创建一个类标记上@Aspect注解,写两个方法,一个方法完成执行切点之前的操作,另一个完成执行切点之后的操作,并分别加上@Befor@After注解。再在xml中配置。
4.整合MyBatis
MyBatis中有一个总配置文件和许多个用来实现接口的mapper.xml配置文件,而Spring的工作主要就是取代或简化总配置文件。
MyBatis的使用流程为:
- 在总配置文件中配置好数据库
- 使用SqlSessionFactoryBulider载入配置文件创建SqlSessionFactory对象
- 使用SqlSessionFactory创建SqlSession对象
spring对应的取代方法为:
- 在总配置文件中创建DriverManagerDataSource对象取代数据库
- 在总配置文件中创建SqlSessionFactoryBean对象取代SqlSessionFactory
- 在总配置文件中创建SqlSessionTemplate对象取代SqlSession
- 注意:使用spring整合mybatis需要额外创建一个类实现mapper接口并在该类中声明sqlsession,然后在spring中创建该类并注入sqlsession(因为在service层要用到mapper接口的方法所以要在service层创建mapper对象,而如果没有一个实现类是无法在spring中给该mapper对象赋值的)当然也可以用另一种扫描的方式,不用mapper实现类也可为service中的mapper接口注入值。
5.整合MVC
MVC的执行流程为:
- url匹配web.xml中的servlet,从而执行该servlet
- servlet中通过httprequest对象获取请求参数,通过httpresponse对象设置响应返回值,通过转发和重定向跳转视图
spring对应流程为:
- 无论url如何,都会被dispatchservlet接收,dispatchservlet再解析url通过处理器和适配器找到对应controller中函数,从而执行该controller中函数
- controller中函数的参数用来接收请求参数,通过model对象设置响应返回值,通过函数返回值传给视图映射器从而跳转视图
注意:如果controller设置了@RestController或controller中方法设置了ResponseBean,则函数返回值即响应返回值,而不会用来跳转视图。