浅谈Spring IoC容器

目录

1.IoC容器

2.如何实现一个IoC容器(底层实现)

3.依赖注入


1.IoC容器

IOC: Inversion of Control,控制反转,是一种设计思想。

传统应用中,在对象中主动控制去直接获取依赖对象,这个是正转;反转则是由容器来创建及注入依赖对象,对象只是被动的接受依赖对象。

在spring框架中,Spring 通过IoC容器进行管理所有Java对象的实例化和初始化,控制对象与对象之间的依赖关系。

IoC管理的对象称为Bean,它与使用关键字new创建的java对象没有区别。所以我们可以理解为,IoC就是帮助我们将java对象的创建、管理及对象和对象之间的维护权交由spring框架进行负责。

IoC容器中使用map集合(map<String,Object>类型)存放Bean对象。

2.如何实现一个IoC容器(底层实现)

下面是IoC容器创建Bean的过程:

展开来说,IoC的底层实现如下:

  1. 首先通过注解或是xml文件的形式,定义Bean的相关信息(如id、name之类的),并通过相关抽象工具类(BeanDefinitionReader)读取Bean的定义信息,存入IoC容器中。
  2. 接着,通过CreateBeanFactory创建出一个Bean工厂;然后开始循环创建对象。因为容器中的Bean默认都是单例的,所以优先通过getBean, doGetBean从容器中查找;如果Bean不存在,通过createBean, deCreateBean方法,以反射的方式创建Bean;
  3. 最后,进行对象的属性填充(populateBean);并进行其他初始化操作(initializingBean)。

所以,根据以上原理,如何实现一个IoC容器?

先准备一个基本的容器对象,包含一些map结构的集合,用以存储具体的对象;

然后,进行配置文件的读取工作或者注解的解析工作,将需要创建的Bean对象都封装成BeanDefinition对象存储在容器中;

接着,容器将BeanDefinition对象通过反射的方式进行实例化;

实例化完成后,进行对象的初始化,也就是给类中的对应属性值就行设置(即依赖注入),完成对象的创建,变成一个完成的Bean对象,存储于容器的某个map结构中。

我们只能通过容器对象来获取对象,进行对象的获取和逻辑处理工作。

3.依赖注入

依赖注入:指在Spring创建对象的过程中,将对象依赖属性通过配置进行注入(类似于一个实体类Student中的属性包含另一个定义好的实体类Person,Person类就是注入到的Student中的类)。

依赖注入是对IoC的具体实现。

Spring中我们一般使用两个注解进行依赖注入:

  • 1、@Autowired
  • 2、@Resource

@Autowired注解:根据类型进行装配。主要有以下4种注入方式,其中,属性注入为最常用的注入方式:

    //属性注入
    @Autowired
    private UserDao userDao;

    //set注入
    private UserDao userDao;
    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    //构造注入1
    private UserDao userDao;
    @Autowired
    public UserServiceImpl(UserDao userDao){
        this.userDao = userDao;
}

    //构造注入2
    private UserDao userDao;
    public UserServiceImpl(@Autowired UserDao userDao){
        this.userDao = userDao;
    }

上述代码皆为在ServiceImpl类中注入Dao类代码。需要注意的是, 如果只有一个有参构造方法时,@Autowired注解可以省略。即上述构造注入1、2中@Autowired注解都可以省略。

如果一个类型下有两个实现类,@Autowired注解无法正常根据类型进行注入,此时我们需要使用@Qualifier注解指定Bean的名称。

@Resource注解:根据名称进行装配,未指定name时,使用属性名作为name并根据属性名称进行注入,当name找不到时,会自动根据类型进行装配。

    //无指定名称,根据类型注入
    @Resource
    private UserService userService;
    
    //根据属性名称注入
    @Resource
    private UserService myUserService;
    
    //根据指定名称注入
    @Resource(name = "myUserService")
    private UserService userService;

区别:@Resource注解是JDK拓展包中的注解,更具有通用性;@Auotwired是spring中的注解。@Resource只能使用在属性及set方法上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值