01 Spring-IOC

Spring框架主要解决了创建对象、管理对象的问题

在开发实践中,Spring框架的核心价值在于:开发者可以通过Spring框架提供的机制,将创建对象、管理对象的任务交给Spring来完成,以致于开发者不必再关心这些过程,当需要某个对象时,只需要通过Spring获取对象即可。        Spring框架也经常被称为 Spring容器

  • Spring框架2大核心功能:
    • IOC:        控制反转
    • AOP:       面向切面编程

将对象的创建权交由Spring去管理,我们需要使用某个对象时,直接从Spring框架获取即可使用。

之前创建对象的步骤:
    class A{}
    class Test{
        main:
            A a = new A(); //由我们自己创建的
    }
Spring框架中对象的创建:
    对象不需要由我们创建,Spring框架已经帮我们创建好了所有的对象,
    使用时直接从Spring框架获取对象使用即可。

    class B{}
    class Test{
        main:
        //不能这样做
        //new B();
        //正确的做法:
        从Spring容器中获取B对象
    }

     

模块目标:

  • 定义Spring Bean
  • 在Application Context中访问Bean
  • Bean的配置
  • 组件扫描和BeanId的命名规则
  • 依赖注入Bean
  • Bean的作用域
  • 组合注解和元注解

 

定义Spring Bean

  • 定义类,并将类交由Spring去管理,如何实现?        

1. 显示配置Bean

使用2个注解配合使用,具体做法是:

                1. 在项目定义配置类 -- 通过注解@Configuration类定义配置类

                        @Configuration作用于类上方,则表面这个类是一个配置类

                2. 在配置类中定义Bean -- 告诉Spring容器需要去创建哪些Bean对象

判断Spring容器是否已经定义Bean对象的方式:从Spring容器获取该Bean对象

案例步骤:

         1. 创建SpringBoot项目

         2. 创建包:config用于放配置类 dao包用于保存一些定义的类

         3. 创建类:在config包下创建配置类,类名自定义 在dao包下创建UserDao类

         4. 配置Bean

             在配置类上方添加注解@Configuration

             在配置类中定义一个方法用于返回UserDao实例,在该方法上方添加注解@Bean

         5. 测试Spring是否已经配置好了Bean对象

             获取ApplicationContext对象,然后调用getBean方法获取UserDao实例,如果获取成功,表明Spring配置UserDaoBean成功

注意点:通过@Bean显示配置Bean对象,方法名即为Bean对象的id/name,通常我们叫做BeanId,BeanId是用于检索Bean对象的

通过@Bean装配Bean时,若需要注入其他Bean对象,可以使用参数注入Bean对象

@Bean
public PersonService personService(PersonDao personDao){
         return new PersonServiceImpl(personDao);
}

2. 隐式配置Bean

1. 通过在类上方添加组件类注解来表明某个类是组件,交由Spring去管理

组件:Spring中定义的类,通过在类上放添加注解来表明是组件

2. 

组件类注解:

        @Component        通用组件注解

        @Controller / @RestController        控制器组件

        @Service        业务层组件

        @Repository        持久层/数据层组件

        @Configuration        表示配置类组件

隐式配置的BeanId

1. 若类名是首字母大写,第二个字母小写,则beanId为类名首字母小写:

        eg:class DogDaoImpl        对应的BeanId为dogDaoImpl

2. 否则,BeanId和类名保持一致。

        eg:class DOgDaoImpl        对应的BeanId为DOgDaoImpl

隐式配置的BeanId也可以通过在注解@Component("BeanId") 指定BeanId

关于显示配置和隐式配置的选择:

在定义自己写的类时,建议使用隐式配置

若想将不是自己写的类装配成Bean时,建议使用显示配置

Spring中所有Bean的创建时机

Spring框架中,所有的Bean对象都是在Spring程序启动时实例化好的。

因为以上操作,造成的现象:启动Spring程序,启动时间会长一些

问题:为什么Spring不启动懒加载机制(即什么时候用某个Bean,再创建某个Bean对象)

        如果在程序启动时实例化所有的Bean,这种方式程序启动时间会长,但是后续使用Bean时无需再创建Bean,所以使用过程中销量高。

        如果采用懒加载方式,即程序启动时不实例化Bean,而是什么时候用,什么时候再实例化,这种方式会降低程序的使用效率。

从Spring容器中获取Bean对象

  • ApplicationContext -- 应用程序上下文对象

该对象代表Spring容器,会存在于整个项目生命周期中。

所以可以通过该对象获取Spring容器中的所有Bean对象

  • 如何获取ApplicationContext对象

ApplicationContext context = SpringApplication.run(...);

  • 如何通过ApplicationContext对象获取某个Bean对象 -- 三种方式

1. 根据数据类型来获取某个Bean对象

        UserDao dao = context.getBean(UserDao.class);

        注意点:这种获取方式要求:该类型的Bean对象只有一个

2. 根据BeanId来获取Bean对象

        StudentDao studentDao = (StudentDao) context.getBean("studentDao");

        注意点:通过BeanId获取到的Bean对象类型为obj

                      etc,需要强转

3. 根据BeanId来获取Bean对象,可以指定数据类型,无需强转

        UserDao userDao = context.getBean("userDao",UserDao.class);

Bean的作用域

  • 作用域是Bean的属性,可以单独对某个Bean的作用域进行修改
  • Spring容器配置Bean对象时,默认所有的Bean对象都是单例的。
  • Spring容器中Bean的常见作用域:

singleton        --        单例        Spring容器默认的

prototype       --        原型        每次获取Bean对象,都会重新实例化

request         --       每个request对象代表一次请求,每发起一次请求,都会重新实例化用到的Bean对象

session         --        每次用户会话创建一个新的session对象,都会重新实例化用到的Bean对象

  • 如何修改作用域:
    • 通过注解@Scope来定义,用法为:

@Bean

@Scope("prototype")

public UserDao userDao(){

        return new UserDao();

}

依赖注入

@Autowired注入

  • 该注入是Spring框架提供的注解
  • 默认是根据类型来匹配的

@Autowired的三种注入方式

1. 构造方法注入(推荐的做法)        必须存在唯一的匹配类型的依赖

@Autowired public CatServiceImpl(AnimalDao animalDao){

        this.animalDao = animalDao;

}
 

2. set方法注入

@Autowired

public void setBearDao(BearDao bearDao){

        this.bearDao = bearDao;

}

3. 字段注入

@Autowired

private CatDao catDao;

  • @Autowired可能会产生歧义的问题

案例:

        //可以注入的对象有多个

        interface userDao{}

        class userDaoImpl implements UserDao{}

        class userDaoImpl1 implements UserDao{}

        class UserServiceImpl 实现UserService{

                @Autowired

                private UserDao userDao;

}

  • @Autowired消除歧义 -- 2种解决办法
    • 1. 使用注解@Qualifier(适用于方法注入和属性注入,不适用于构造方法注入)

步骤:

        定义一个UserDao接口,两个实现类

        在UserServiceImpl中通过字段注入UserDao对象,看是否产生歧义

        测试@Qualifier注解是否可以解决歧义

                @Qualifier只能作用于set方法注入和字段注入

  • 2. 解决歧义的第二种方法
    • @Autowired 若产生歧义,此时默认会自动根据 beanId 去找是否有对应的 Bean ,若有,
      则直接注入。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值