Spring IOC

IOC原理

IOC即控制反转,意思是对象的创建不通过 手动 new,而是把对象的创建权交给Spring来完成,由spring来负责控制对象的生命周期和对象间的关系。

DI 即依赖注入,意思是 Spring在系统运行中,动态的向某个对象提供它所需要的其他对象。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

使用IOC

1. 使用XML配置文件

<bean id="helloWorld" class="com.vae.springboot.bean.HelloWorld">
    <property name="userName" value="pjy"></property>
</bean>

class 为类的路径
id 后面用于获取对象

IOC容器getBean的三种方法:

  1. 根据Bean对象在容器中的id来获取
helloWorld= (HelloWorld)factory.getBean("helloWorld");
  1. 根据类型获取Bean
helloWorld= factory.getBean(HelloWord.class);
  1. 根据id+类型来获取Bean
helloWorld= factory.getBean("helloWorld",HelloWord.class);

xml配置文件的import导入

我们的applicationContext.xml里面写的是Bean,一个项目里面那么多需要控制反转的,难道我们写上千个Bean?这样都写在一个xml文件里,太大,也太乱,所以我们可以分开写每个包里面写个自己的xml,然后applicationContext.xml直接import导入就可以了

 <!--导入其他的配置文件-->
    <import resource="classpath:com.vae.springboot.bean.HelloWorld.xml"></import>

2. 使用注解

@Configuration标注在类上,相当于把该类作为spring的xml配置文件,作用为:配置spring容器(应用上下文)
@Bean标注在方法上(返回某个实例的方法),等价于spring的xml配置文件中的,作用为:注册bean对象

 1package config;
 2
 3import model.User;
 4import org.springframework.context.annotation.Bean;
 5import org.springframework.context.annotation.Configuration;
 6import org.springframework.context.annotation.Scope;
 7
 8@Configuration
 9public class TestConfiguration {
10
11    public TestConfiguration(){
12        System.out.println("TestConfiguration 容器启动初始化...");
13    }
14
15    @Bean
16    @Scope("prototype")
17    public User user(){
18        return new User();
19    }
20}

# Bean的作用域
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021020210390197.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMDgyMzA3,size_16,color_FFFFFF,t_70)
# IOC容器
1. BeanFactory
2. ApplicationContext

ApplicationContext这个其实是BeanFactory的一个子接口

BeanFactroy采用的是延迟加载形式来注入Bean的(懒汉式),即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
ApplicationContext,它是在容器启动时,一次性创建了所有的Bean(饿汉式)。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了

# Bean的生命周期
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210202105029666.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMDgyMzA3,size_16,color_FFFFFF,t_70)

如上图所示,Bean 的生命周期还是比较复杂的,下面来对上图每一个步骤做文字描述:

1. Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化

2. Bean实例化后对将Bean的引入和值注入到Bean的属性中

3. 如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法

4. 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入

5. 如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。

6. 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。

7. 如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用

8. 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。

9. 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。

10. 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。

> https://www.cnblogs.com/javazhiyin/p/10905294.html


```注: 
(1)@Bean注解在返回实例的方法上,如果未通过@Bean指定bean的名称,则默认与标注的方法名相同; 
(2)@Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为原型作用域; 
(3)、既然@Bean的作用是注册bean对象,那么完全可以使用@Component@Controller@Service@Repository等注解注册bean,当然需要配置@ComponentScan注解进行自动扫描。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值