Spring IOC(Inversion Of Control)---->控制反转,依赖注入
简单地来说:
控制反转就是原先由程序员主动通过new的实例化对象,通过Spring就不需要去自己手动new对象,我们只需要将控制权交给Spring,让Spring帮我们来完成这个过程
依赖注入:告诉Spring我们需要什么,然后自己从Spring那里拿到控制权
IOC最大的作用:解耦—>解除了对象管理和程序员之间的耦合
下面用几张图解释一下
原先类与类之间有非常复杂,难以解耦如下图
但是有了Spring以后,就可以把所有类的控制权假如Spring中,让Spring来调控管理
这个功能看起来十分简单,但在日常处理非常庞大的代码量时,这个功能实际上给程序员省了非常非常多的事
SpringIOC环境搭建:
1、添加maven jar包到项目中去
需要添加以下几个jar包
* spring context
* spring beans
* spring core
* spring aop
* spring tx
*
2、添加spring的核心配置文件在resource文件中
applicationContext.xml ------>本质上就是【spring、spring框架,spring容器,spring技术】
Spring使用
1、建立两个相互耦合的类用于实验
类A:
public class A {
private B b;
public A(){
}
public A(B b){
this.b=b;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public void callme(){
System.out.println(b.sayHallow("hellow"));
}
}
类B:
public class B {
private String name;
public B(){
}
public B(String name){
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String sayHallow(String message){
return "myname is"+message;
}
}
假设A类中有一个属性b,b的类型是类B,那么这个时候如何不在A中new B而是直接通过Spring来拿到其中的方法呢?
先配置application.xml文件 文件配置方法如下
<bean id="b" class="com.jia.B">
<property name="name" value="huahua"/>
</bean>
<bean id="a" class="com.jia.A">
<property name="B" ref="b"/>
</bean>
在其中添加Bean中添加类A和类B,这一步的意义就是将类A和类B添加进了Spring容器内,那么如何调用呢?
在test文件中
public class ABTest {
private ApplicationContext context = null;
@Before
public void initMethod(){
context = new ClassPathXmlApplicationContext(new String[]{"applicationContext-first.xml"});
}
@Test
public void testRelevantAAndB(){
A a=(A)context.getBean("a");
System.out.println(a.getB().sayHallow("hi"));
}
}
通过ClassPathXmlApplicationContext类中的getBean方法拿到类B的控制权,就可以直接调用B中的方法,获取B中的属性,但这一系列动作底层其实都是通过反射完成的,以上动作只是初学者初用SpringIOC调用对象的操作,以后会有简洁的操作,这里先暂且不论。
IOC容器简介
Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化 Bean 并建立 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;
ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的 BeanFactory。
Bean的生存周期
1.当调用者通过 getBean(beanName)向容器请求某一个 Bean 时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor 接口,在实例化 Bean 之前,将调用接口的 postProcessBeforeInstantiation()方法;
2.根据配置情况调用 Bean 构造函数或工厂方法实例化 Bean;
3.如果容器注册了 InstantiationAwareBeanPostProcessor 接口,在实例化 Bean 之后,调用该接口的 postProcessAfterInstantiation()方法,可在这里对已经实例化的对象进行一些“梳妆打扮”;
4.如果 Bean 配置了属性信息,容器在这一步着手将配置值设置到 Bean 对应的属性中,不过在设置每个属性之前将先调用InstantiationAwareBeanPostProcessor 接口的postProcessPropertyValues()方法;
5.调用 Bean 的属性设置方法设置属性值;
6.如果 Bean 实现了 org.springframework.beans.factory.BeanNameAware 接口,将调用setBeanName()接口方法,将配置文件中该 Bean 对应的名称设置到 Bean 中;
7.如果 Bean 实现了 org.springframework.beans.factory.BeanFactoryAware 接口,将调用 setBeanFactory()接口方法,将 BeanFactory 容器实例设置到 Bean 中;
8.如果 BeanFactory 装配了 org.springframework.beans.factory.config.BeanPostProcessor后处理器,将调用 BeanPostProcessor 的 Object postProcessBeforeInitialization(Object bean, String beanName)接口方法对 Bean 进行加工操作。其中入参 bean 是当前正在处理的 Bean,而 beanName 是当前 Bean 的配置名,返回的对象为加工处理后的 Bean。用户可以使用该方法对某些 Bean 进行特殊的处理,甚至改变 Bean 的行为, BeanPostProcessor 在 Spring 框架中占有重要的地位,为容器提供对 Bean 进行后续加工处理的切入点, Spring 容器所提供的各种“神奇功能”(如 AOP,动态代理等)都通过 BeanPostProcessor 实施;
9.如果 Bean 实现了 InitializingBean 的接口,将调用接口的 afterPropertiesSet()方法;
10.如果在通过 init-method 属性定义了初始化方法,将执行这个方法;
11.BeanPostProcessor 后处理器定义了两个方法:其一是 postProcessBeforeInitialization() 在第 8 步调用;其二是 Object postProcessAfterInitialization(Object bean, String beanName)方法,这个方法在此时调用,容器再次获得对 Bean 进行加工处理的机会;
12.如果在中指定 Bean 的作用范围为 scope=“prototype”,将 Bean 返回给调用者,调用者负责 Bean 后续生命的管理, Spring 不再管理这个 Bean 的生命周期。如果作用范围设置为 scope=“singleton”,则将 Bean 放入到 Spring IoC 容器的缓存池中,并将 Bean引用返回给调用者, Spring 继续对这些 Bean 进行后续的生命管理;
13.对于 scope=“singleton”的 Bean,当容器关闭时,将触发 Spring 对 Bean 的后续生命周期的管理工作,首先如果 Bean 实现了 DisposableBean 接口,则将调用接口的afterPropertiesSet()方法,可以在此编写释放资源、记录日志等操作;
14.对于 scope=“singleton”的 Bean,如果通过的 destroy-method 属性指定了 Bean 的销毁方法, Spring 将执行 Bean 的这个方法,完成 Bean 资源的释放等操作。