1.IOC-控制反转
简单来说就是将对象创建的权力和对象生命周期的管理过程交由Spring框架处理,在需要时由Spring框架提供,这种机制称为控制反转。
2.IOC入门案例
1)访问Spring官网并下载Spring相关的包
2)解压下载好的安装包
3)用eclipse或者myeclipse创建一个java项目(普通的也可以)
4)导入相关jar包
外部:commoms-loggingxxx.jar
Spring的libs目录下:
spring-beansxxx.jar
spring-contextxxx.jar
spring-context-supportxxx.jar
spring-corexxx.jar
spring-expressionxxx.jar
spring-testxxx.jar
共6个jar包
5)通常创建名为applicationContext.xml的配置文件并将其放在类加载目录(src目录)下
6)创建bean类,并在spring中进行配置交由spring来管理
7)在程序中通过Spring容器获取对象并使用
public void test1(){
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
Person p = (Person) context.getBean("person");
p.say();
}
3.IOC的实现原理
初始化一个Spring容器时,Spring会去解析指定的xml文件,当解析到<bean>标签时,会根据标签中的class属性中类的全路径名,通过反射来创建该类对象,并将该对象存入内置的map中管理。键就是标签的id值,值就是该对象,之后通过getBean()方法从容器中获取对象其实就是根据传入的条件在内置map中寻找匹配的键值,有则返回,无则抛出异常
由上述可知:
1)默认情况下,获取同一个id的bean得到的是同一个对象
2)同一个类如果配置多个具有不同id的<bean>标签,每个id都会在内置map中有一个独立的键值对,其中的值是这个类的不同对象
3)同一个<beans>标签下不允许配置多个同id的<bean>标签,如果配置,启动会报异常
4.IOC获取对象的方式:
通过getBeans()方法获取bean时,有两种方法:
1)传入id值
2)传入class类型
在使用class获取bean时可能同一个类会配置过多个bean,则在获取时无法确定获取那个bean,导致抛出异常。所以建议使用id获取bean
5.别名标签
Spring中提供了<alias name="要起别名的bean的id" alias="要指定的别名">,注意这仅仅是起一个额外的名字,并不会额外创建对象存入map
6.Spring创建对象的四种方法
1)通过类的无参构造方法创建对象
核心:在xml文件中配置<bean>时默认采用类的无参构造,在Spring容器初始化时通过<bean>上配置的class属性反射得到字节码,再用newInstance()创建对象,如果该类没有无参构造,使用这种方法会抛出异常
2)通过静态工厂创建对象
核心:创建一个工厂类,在其中写一个用来创建对象的静态方法,在配置文件的<bean>标签下再添加一个factory-method属性,值为工厂类中创建对象的静态方法名。
3)实例工厂创建对象
核心:与静态工厂类似,只不过工厂类中用来创建对象的方法是普通方法,所以Spring需要先创建出实例工厂的对象,再调用普通方法,因此实例工厂也需要配置到Spring中管理
4)Spring工厂创建对象
写一个类实现FactoryBean<T>接口,重写其中的方法,通过这个工厂创建对象
7.单例和多例
Spring容器在默认情况下是单例的,即:一个bean只会创建一个对象并将其存在内置的map中,之后无论获取多少次该bean,都返回同一个对象。
1)bean在单例模式下的生命周期
单例模式下的bean,在Spring容器启动时会直接创建该bean的对象并将其存入map中,之后无论使用多少次getBean()获取该bean,得到的都是同一个对象,该对象一直被Sring容器所持有,一直到容器退出时才会被销毁
2)bean在多例模式下的生命周期
多例模式下的bean,在Spring容器启动时只是将该bean进行管理,并不创建对象,之后每调用一次getBean()方法,都会创建一个新的对象,Spring容器不会持有该对象,其什么时候销毁取决于使用该对象的用户
8.懒加载机制
Spring默认的加载机制(容器在初始化时解析xml,并将单例的bean创建并保留在map中)在bean非常多时,Spring需要花大量的时间和存储空间来解析xml和存储bean,造成资源的浪费。
出于以上情况,Spring提供了懒加载机制。即:在第一次使用时才创建bean。
注意:懒加载机制只对单例bean有作用,对于多例bean,设置懒加载没有意义。
懒加载的两种配置方式:
1)在bean标签中添加lazy-init="布尔值"属性,这只会影响单个bean
2)在beans标签中添加default-lazy-init="布尔值",来为全局配置懒加载
ps:单个配置会覆盖全局配置
9.如果Spring中的某个bean需要在初始化之后或者被销毁之前做一些操作,可以在该bean中配置初始化和销毁的方法,在这些方法中完成要实现的功能
init-method="初始化方法名"
destroy-method="销毁方法名"
ps:如果虚拟机突然"死亡",会来不及调用销毁的方法,只有在容器正常退出之前才会执行销毁的方法
10.Spring中方法的执行顺序:
Spring创建bean对象(通过无参构造或工厂),之后立即调用初始化方法执行初始化操作,之后此bean对象就可以拿来调用其他普通方法,最后Spring容器在对象销毁之前调用销毁方法