IOC
两个容器
容器的两个实现类的差别:
ClassPathXmlApplicationContext()是从当前项目的类路径下查找,也就是src下
FileSystemXmlApplicationContext()是从根目录下(即与src是平级的位置)或者从盘符下找查找,
创建对象时,在执行构造器之前就已经将内存分配好了,而不是在执行完构造方法以后才分配的内存
一个没有成员变量的对象在堆内存中占有8个字节
ApplicationContext与BeanFactory容器的区别:
这两个容器对于其中Bean的创建时机不同
(1)ApplicationContext容器在进行初始化时,会将其中的所有Bean(对象)进行创建
缺点:占用系统资源(内存,CPU)
优点:响应速度快
(2)BeanFactory容器中的对象,在容器初始化时并不会被创建,而是在真正获取该对象时才被创建
缺点:相应来说,响应速度慢
优点:不多占用系统资源
IOC
默认采用无参构造生成Bean
容器中Bean的作用域
(1)原型模式:
scope=“prototype” 原型模式,其对象的创建时机不是在Spring容器初始化时创建,而是在代码中真正访问时才创建(访问几次创建几次)。
(2)单例模式:
scope=“singleton” 单例模式,其对象的创建时机时在Spring容器初始化时创建,是默认值(对象只有一个)。
Bean后管理器
添加类并实现BeanPostProcessor接口,实现两个方法,在每个Bean初始化之前会执行一个方法,在每个Bean初始化之后又会执行一个方法。可以用这一特性来增强Bean的功能,返回功能更加强大的Bean
定义Bean的生命周期始末
可以在bean标签中添加init与destory属性来指定bean创建之后和销毁之前执行什么方法。对于销毁方法的执行,有两个条件:
(1)当前的Bean需要时是单例的。
(2)需要手动关闭容器。
ClassPathXmlApplicationContext中有close方法,需要将容器强转类型。
基于XML的DI
注入分类
依赖注入:
(1)设值注入:需要在javabean中加入set方法,并在bean标签中添加property属性来对对应的属性赋值(执行set方法)(2)构造注入:使用构造器,需要在javabean中添加带参数的构造方法,并在bean标签中添加name和值value或者ref
主要使用设值注入,构造注入使用较少。
集合属性注入
在property标签下加入对应的集合标签(array list set map props),并在集合标签中根据数据的类型选择value或ref或entry或prop进行注入。
对于域属型的自动注入
byName方式:会从容器中查找与属性与实体类的域属性同名的id,需要在bean标签中加入autowire属性并赋值byName
byType方式:会从容器中查找与实体类的域属性类型具有is a关系的(包括子类)
SPEL注入
对value赋值采用"#{}"的形式,#{}中的内容可以调用类的方法,可以调用别的bean的属性(通过id名.属性名)也可以放置表达式进行判断
对于内部bean的注入
(1)同类抽象bean:抽取出相同类类型的内容相同的语句组成BaseBean,用parent属性让其它bean继承它,子类中不加class属性,因为父类中包含。同时要将父类bean中加入属性abstract并将其值设置为true(设为抽象类)此时这个类就叫做同类抽象bean,为了不让单独调用(因为没有意义)
(2)异类抽象类:抽取出不同类中相同属性的语句组成bean,用parent属性让其它bean继承它,子类中加class属性,因为是不同的类,但父类中不用加class属性,但得加abstract属性并将其设置为true,父类即为异类抽象类
为应用指定多个Spring配置文件
(1)平等关系:各个配置文件属于同一级别,使用通配符完成对所有文件的加载,这就要求他们的前缀相同。
(2)包含关系:在主文件中加入import标签并加入recource属性,属性赋值为"classpath:(当在类路径下时加classpath)文件路径"在主文件下也可使用通配符(此时主配置文件前缀不要和子文件相同,否则会有歧义)在类前加@component表示当前类被Spring容器所管理
基于注解的DI
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解的扫描:扫描该包下的所有类 -->
<context:component-scan base-package="priv.ze.spring.IOC.test01"/>
</beans>
定义Bean@component
在类前加@component表示当前类被Spring容器所管理,component表示组件
基本类型赋值:在基本类型前加@Value并在括号内赋值
Bean的作用域@Scope
在类前加上该注解并在括号内赋值
基本类型属性注入@Value
在类中基本数据类型前加入注解并赋值
域属型注解
Spring自带:
(1)在域属型前加@Autowired属性通过byType方式的注解式注入,不用加参数
(2)在域属型前加和@Autowired@Qualifier注解通过ByName方式进行注入,这两个注解必须联合使用
JSR-250规范(JSK6以上版本):
(1)ByName方式:在域属型前加@Resource(name=" ")
(1)ByType方式:在域属型前直接使用@Resource
Bean的生命始末@PostConstruct与@PreDestroy
在对应方法前加上相应的注解,但注意对于@PreDestroy只添加注解是不够的,不许还要关闭容器并且设置该类是单例的
使用JUnit4测试Spring
在单元测试类前加入@RunWith注解并赋值SpringJunit4classRunner,同时添加@ContextConfiguration注解并赋值location=“classpath:…”(此时默认使用的是类路径下的创建容器的方法)
因为得到对象需要容器,但此时并没有容器的引用,所以需要使用注解得到相应对象的引用,创建该对象的引用但不赋值,在创建语句之前加上@AutoWire标签(通过ByType进行赋值),当然也可以使用NyName。
XML的优先级要高于注解的
若XML与注解同时配置Bean,则会优先执行XML的。
注解方式不需要set方法,但是设值注入需要使用get方法,建议不要将set方法删掉,这样万一以后需要改信息可以直接在XML中进行修改,避免了对代码的重新编译