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的三种方法:
- 根据Bean对象在容器中的id来获取
helloWorld= (HelloWorld)factory.getBean("helloWorld");
- 根据类型获取Bean
helloWorld= factory.getBean(HelloWord.class);
- 根据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的作用域

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

如上图所示,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注解进行自动扫描。