Spring之IoC

文章目录

    • 一.SpringIoC核心概念
      • 1.IOC(Inversion of Control)控制反转
      • 2.DI(Dependency Injection)依赖注入
    • 二.bean的实例化
      • 1.构造方法实例化bean
      • 2.静态工厂方法实例化bean
    • 三.Bean的生命周期
      • 1.Bean的实例化
      • 2.设置属性
      • 3.Bean初始化
      • 4.bean的使用和销毁

一.SpringIoC核心概念

IOC、IOC容器、Bean、DI

1.IOC(Inversion of Control)控制反转

  1. 什么是控制翻转?

当我们需要使用对象的时候,我们一般会new来产生对象,但使用IoC思想后,我们获取对象不再是主动new对象,而是将该对象的创建控制权交给‘外部’,由‘外部’创建对象并交给我们。

  1. Spring和IoC之间的关系是什么?

IoC是一种思想,Spring对IoC进行了实现
Spring提供一个容器,名为IoC容器,充当IoC容器中的‘外部’

  1. IoC容器的作用是什么?

IoC容器存放了一个个的bean对象
IoC容器负责对象的创建,初始化等一系列工作

2.DI(Dependency Injection)依赖注入

  1. 什么是依赖注入?

容器中建立bean与bean之间的依赖关系的整个过程,就叫做依赖注入

总结:DI可以认为是IoC的一种具体实现

二.bean的实例化

对象已经能交给Spring的IOC容器来创建了,但是容器是如何来创建对象的呢?这就需要了解bean的实例化过程了

实例化bean可以通过配置文件来实现,但过于繁琐,下面所有内容将尽量使用注解来完成

1.构造方法实例化bean

顾名思义,bean其实就是一个对象,对象实例化自然就会调用自己的构造函数

使用@Componet注解

@Component("bookDao")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ..." );
   }
}

之前没使用注解的时候,需要手动在配置文件中配置,使用完注解后,只需要配置spring的扫描包路径,就会达到和在配置文件中定义bean一样的效果

注意:Spring底层使用的是无参构造函数来实例化bean的。

2.静态工厂方法实例化bean

首先,我们需要创建一个配置类,并在这个类上添加@Configuration注解:

@Configuration  
public class AppConfig {  
    // ...  
}

然后,在这个配置类中添加一个工厂方法,并在这个方法上添加@Bean注解:

@Configuration  
public class AppConfig {  
  
    @Bean  
    public MyBean myBean() {  
        return new MyBean();  
    }  
  
    // ...  
}

静态的工厂方法

public class MyBeanFactory {  
    public static MyBean createMyBean() {  
        // 创建并返回MyBean实例的代码  
    }  
}

最后

@Configuration  
public class AppConfig {  
  
    @Bean  
    public MyBean myBean() {  
        return MyBeanFactory.createMyBean();  
    }  
  
    // ...  
}

三.Bean的生命周期

Bean的生命周期注意可以分为五个部分:1.Bean的实例化,2.设置属性,3.Bean的初始化方法,4.使用,5.销毁

1.Bean的实例化

上文已经讲述不再赘述了

2.设置属性

依赖注入指的是建立bean与bean之间的依赖关系,设置属性有三种方式:1.属性注入(Autowire),2.setter注入,3.构造器注入

属性注入

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  
  
@Component  
public class MyClass {  
    @Autowired(required = false)  
    private MyDependency myDependency;  
      
    // ... 其他代码 ...  
}

setter注入

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  
  
@Component  
public class MyClass {  
    private MyDependency myDependency;  
  
    @Autowired  
    public void setMyDependency(MyDependency myDependency) {  
        this.myDependency = myDependency;  
    }  
      
    // ... 其他代码 ...  
}

构造器注入

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  
  
@Component  
public class MyClass {  
    private MyDependency myDependency;  
  
    @Autowired  
    public MyClass(MyDependency myDependency) {  
        this.myDependency = myDependency;  
    }  
      
    // ... 其他代码 ...  
}

总结:实例化和初始化的区别

实例化和属性设置是 Java 级别的系统“事件”,其操作过程不可⼈⼯⼲预和修改;⽽初始化是给开发者
提供的,可以在实例化之后,类加载完成之前进⾏⾃定义“事件”处理。

3.Bean初始化

1.实现了各种 Aware 通知的⽅法,如 BeanNameAware、BeanFactoryAwared,ApplicationContextAware
例如:

public class MyBeanFactory implements BeanFactoryAware {
    private BeanFactory beanFactory;
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
    public void getMyBeanName() {
        MyBeanName myBeanName = beanFactory.getBean(MyBeanName.class);
        System.out.println(beanFactory.isSingleton("myCustomBeanName"));
    }
}

通过beanFactory我们就可以手动获取IoC容器中的bean了

ApplicationContextAware 的接⼝⽅法

@Component
public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext context;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
    public static ApplicationContext getApplicationContext(){
        return context;
    }
 }

作用和BeanFactoryAware接口类似,都是获取spring上下文
2.执⾏ BeanPostProcessor 初始化前置⽅法

public class MyBeanPostProcessor implements BeanPostProcessor{

/**
 * 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
 * 注意:方法返回值不能为null
 * 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象
 * 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中
 */
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	System.out.println("初始化 before--实例化的bean对象:"+bean+"\t"+beanName);
	// 可以根据beanName不同执行不同的处理操作
	return bean;
}

/**
 * 实例化、依赖注入、初始化完毕时执行 
 * 注意:方法返回值不能为null
 * 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象
 * 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中
 */
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	System.out.println("初始化 after...实例化的bean对象:"+bean+"\t"+beanName);
	// 可以根据beanName不同执行不同的处理操作
	return bean;
}

}

BeanPostProcessor主要作用于初始化方法执行前后

3.执⾏ @PostConstruct 初始化⽅法,依赖注⼊操作之后被执⾏;
4.执⾏⾃⼰指定的 init-method ⽅法(如果有指定的话);
Spring之IoC_第1张图片
5.执⾏ BeanPostProcessor 初始化后置⽅法。

见上述第二条

4.bean的使用和销毁

使用不用多说,bean销毁前也会执行一些销毁方法

销毁容器的各种⽅法,如 @PreDestroy、DisposableBean 接⼝⽅法、destroy-method。
@PreDestroy==DisposableBean

@Component
public class MyBean implements DisposableBean {
    // ...
    
    @Override
    public void destroy() throws Exception {
        // 执行清理操作
        System.out.println("MyBean销毁前执行清理操作");
    }
}

以上就是我对SpringIoC容器的见解,如有错误望指正!

你可能感兴趣的:(spring,java,后端)