Java面试题设计模式篇spring中的IoC和DI

1. 什么是IoC和DI

IoC:控制反转是个设计原则,自定义的程序可以从通用框架接受控制流

DI:依赖注入,是一个技术实现,一个对象可以提供另一个对象的依赖。比如利用组合关系引入另外的对象,其实就是依赖注入

Spring框架拥有一个IoC容器,负责对象创建,装配,配置,管理整个生命周期,直到完全销毁。IoC容器通过依赖注入,也就是DI管理beans。

2 IoC之自定义程序接受Bean控制流

SpringContext负责bean的依赖注入,主要通过以下三种方式:

  • Set方法
  • 构造方法
  • Autowired(原理下篇文章讲解)

上文提到IoC可以让自定义程序从通用框架接受控制流。下面我们就看看如何在自定义程序中获取bean的控制流

  • 实现InitializingBean接口,其中afterPropertiesSet方法会在BeanFactory对bean属性设置完后回调
  • 实现DisposableBean接口,其中destory()方法会在销毁前进行回调

上面两种方式可以实现,但是不建议使用,因为和spring框架的bean实现耦合比较紧

另外一种,通过配置文件属性 init-method 和 destroy-method实现。

在springboot中,也可以利用Annotations实现,@PostConstruct, @PreDestroy Annotations,举例如下:

  @PostConstruct
    private void init() {
        signer = new SvsSign();
        try {
            signer.initSignCertAndKey(this.getClass().getResource(bigGooseCardRsaPrivateKey).getPath(),
                    bigGooseCardRsaPrivateKeyPw);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3 Aware接口

Spring的依赖注入的最大亮点就是你所有的BeanSpring容器的存在是没有意识的。即你可以将你的容器替换成别的容器,例如Goggle Guice,这时Bean之间的耦合度很低。

但是在实际的项目中,我们不可避免的要用到Spring容器本身的功能资源,这时候Bean必须要意识到Spring容器的存在,才能调用Spring所提供的资源,这就是所谓的Spring Aware。其实Spring Aware本来就是Spring设计用来框架内部使用的,若使用了Spring Aware,你的Bean将会和Spring框架耦合

举例子如下:

package com.puhui.goosecard.web.utils;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
public class AwareService implements BeanNameAware, ResourceLoaderAware {//①

    private String beanName;
    private ResourceLoader loader;

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {//②
        this.loader = resourceLoader;
    }

    @Override
    public void setBeanName(String name) {//③
        this.beanName = name;
    }

    public void outputResult() {
        System.out.println("Bean的名称为:" + beanName);

        Resource resource =
                loader.getResource("classpath:org/light4j/sping4/senior/aware/test.txt");
        try {

            System.out.println("ResourceLoader加载的文件内容为: " + IOUtils.toString(resource.getInputStream()));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出结果如下:

aware

4 总结

  •  Spring框架中的bean对于IoC容器是无感知的,你定义的bean甚至可以更换IoC容器,比如google的guice。
  • 如果需要bean感知spring的IoC容器,那么就需要实现Aware接口

猜你喜欢

转载自blog.csdn.net/hanruikai/article/details/81948810