Spring-控制反转(IOC)

控制反转(IOC)

1. 概念

1.1 问题引入

在之前的学习中,已经学会了使用三层架构开发程序,也就是web—>service—>dao,但是在调用的时候层与层之间存在着代码耦合.

1.2 解决思路

Spring解决上述问题的思路其实很简单,它改变了对象的创建者
传统方式:servlet需要service了,就是由Servlet主动创建
Spring方式:所有的对象都是由Spring框架提前创建出来,存储到一个容器中,servlet需要Service了,就向Spring要一个

1.3 IOC概念

IOC( 控制 反转 )是一种设计思想,它的目的是指导我们设计出更加松耦合的程序
控制:指的是对象创建权
反转:指的对象的创建由程序员在类中主动创建反转到由Spring容器来创建

2. 依赖及简单配置

2.1 pom文件依赖导入

pom代码:

    <dependencies>
        <!--spring核心-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.16</version>
        </dependency>

        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
    </dependencies>

2.2 创建接口和实现类

//接口
public interface DeptDao {
    // 保存
    void save();
}
//实现类
//@Component 标注在类上 作用:当Spring扫描到这个注解之后,就会使用当前类创建对象,并将对象放入Spring容器中
//这个对象在容器中会有一个标识(id),默认是当前类名首字母小写(deptDaoImpl),也支持使用value属性自定义
//@Component(value = "deptDaoImpl") 只有一个value时可以省略
@Component("deptDaoImpl")
public class DeptDaoImpl implements DeptDao {
    @Override
    public void save() {
        System.out.println("保存成功");
    }
}

2.3 添加配置类

//这个用于Spring的核心配置类,就相当于原来的xml配置文件
@ComponentScan("com.cy")//组件扫描(注解扫描),它需要我们提供一个包命,只有在这个这个包(及其子包)下类中的注解才会被Spring扫描
public class SpringConfig {
}

2.4 测试

public class SpringTest {
    @Test
    public void test1(){
        //1.读取配置类的信息,初始化Spring容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

        //2.从容器中获取对象(使用对象的标识)
        DeptDao deptDao = (DeptDao) context.getBean("deptDaoImpl");

        deptDao.save();
    }
}

3. 案例细节

3.1 Bean创建

向Spring中声明自己开发的类对象的注解,主要有下面四个

* @Component
	用于实例化对象,它支持一个value属性类定义bean在容器中的唯一标识
	如果不写,默认值为类名的首字母小写

* @Controller  @Service  @Repository
	这三个注解的功能跟@Component类似,他们分别标注在不同的层上。
        @Controller  标注在表示层的类上
        @Service     标注在业务层的类上
        @Repository  标注在持久层的类上
	推荐使用这三个,当一个类实在不好归属在这三个层上时,再使用@Component

3.2 Bean作用域

在类上使用@Scope注解定义Bean的作用域,Spring支持如下五种作用域,我们目前常用的是第一种

- singleton   单例,对于一个类,只会创建一个对象,每次从容器中获取,拿到的都是这个对象
- prototype   多例,对于一个类,每次从容器中获取,都会创建一次,得到一个新的对象
- request      在web环境中,每个请求范围内会创建新的对象
- session      在web环境中,每个会话范围内会创建新的对象
- application  在web环境中,每个应用范围内会创建新的对象

① 单例对象 - singleton
对于一个类来说,只会创建一个对象,每次从容器中获取,拿到的都是这个对象
② 多例对象- prototype
对于一个类,每次从容器中获取都会创建一次,得到一个新的对象

 //测试对象的单例和多例
    @Test
    public void test2(){
        //1.读取配置类的信息,初始化Spring容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

        //2.从容器中获取两次对象(使用对象的标识)
        DeptDao deptDao1 = (DeptDao) context.getBean("deptDaoImpl");
        DeptDao deptDao2 = (DeptDao) context.getBean("deptDaoImpl");

        System.out.println(deptDao1 == deptDao2)//单例:true 多例:false;
    }

3.3 Bean的创建时间

① 单例对象
默认情况下,单例对象会在容器创建时就创建;也可以使用@Lazy将创建时机延迟到第一次获取的时候创建
② 多例对象
多例对象会在每次获取的时候才创建

3.4 Bean获取

Spring容器启动时,会把其中的bean都创建好,如果想要主动获取这些 bean,可以使用容器getBean()方法

- getBean("id")                 使用bean的id从容器中查找对象
- getBean(Bean.class)           使用bean的class类型从容器中查找对象
- getBean("id",Bean.class)      使用bean的id和class类型从容器中查找对象
  • 如果查找的id在容器中不存在,会报错
    NoSuchBeanDefinitionException: No bean named ‘deptDaoImpl1’ available
  • 如果查找的类型在容器中不存在,会报错
    NoSuchBeanDefinitionException: No qualifying bean of type ‘DeptDao’ available
  • 如果查找的类型在容器中存在多个,会报错
    NoUniqueBeanDefinitionException: No qualifying bean of type ‘com.cy.dao.DeptDao’
    available: expected single matching bean but found 2: deptDaoImpl,deptDaoImpl2
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值