理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory
作者:mmseoamin日期:2023-12-11

Spring是一个包含众多工具等Ioc容器

对象这个词在Spring范围内,称为bean

Spring两大核心思想

1.IOC     (IOC是控制反转,意思是控制权反转-控制权(正常是谁用这个对象,谁去创建,)-控制对象的控制权,反转的意思是创建对象的控制权,交给了Spring)

优点:解耦合

高内聚:一个模块内部的关系

低耦合:各个模块之间前的关系

2.AOP

list/map装数据的容器

tomcat装的是web的容器

Spring容器,装的是对象

引入案列(为什么推荐用Spring)

理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory,第1张

上面代码的改动成本太大,耦合性太高

如果改成代码这种,传递的是对象,就直接给对象

不采用生成对象,而是你给我什么我就用什么这种,也就是你需要往里面(就像是下面这个图,在main中传递对象。)

IOC帮助我们做这个工作。

理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory,第2张

Spring可以帮助我们创建对象,可以往里面存,也可以从这个里面取,

我们要做的也就是1.告诉Spring,帮我们创建对象,2.知道如何取出来这些对象

DI是一种实现方式(依赖注入)

@Autowired
    private BookService bookService;

假如说加上,上面的Autowired就相当于下面的这个意思

Autowired:告诉Spring,从容器中取出这个对象,赋值给当前对象的属性

 private BookService bookService;
    
    public BookController(){
        bookService=new BookService();
    }
@Component:告诉Spring,帮助我们存储对象。
@Component
public class BookService {
    @Autowired
     private BookDao bookDao;
//    private BookService bookService;
//
//    public BookController(){
//        bookService=new BookService();
//    }
    public List getBookList() {
        List bookInfos = bookDao.mockData();
        for (BookInfo bookInfo : bookInfos) {
            if (bookInfo.getStatus() == 1) {
                bookInfo.setStatusCN("可借阅");
            } else {
                bookInfo.setStatusCN("不可借阅");
            }
        }
        return bookInfos;
    }
}

MVC提供了注解,前面的RequestMapping。

IOC(依赖对象的创建的控制权,存)一种思想,DI(依赖注入)是一种实现方式

DI是把依赖对象取出来,并且赋给该对象属性(取)

DI主要通过两类注解类型可以实现

IOC提供两类注解

1.类注解:@Controller,@Service,@Respository,@Component,@Configuration

2.方法注解:@Bean

理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory,第3张

package com.example.IOCtry;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
//加上Controller才会不报错,假如不加上Controller就会报错
//@Controller
public class UserController {
public void prin(){
    System.out.println("春节快乐");
}
}
package com.example.IOCtry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class IoCtryApplication {
    public static void main(String[] args) {
        //启动类是帮助我们启动spring,这个命令可以返回一个spring
        //context上下文,就是spring一个运行环境
        ApplicationContext context=SpringApplication.run(IoCtryApplication.class, args);
        //从容器中拿对象
        UserController bean=context.getBean(UserController.class);
        //如果去掉Control注解,就会报错
        bean.prin();
    }
}

会报这个错误,意思是说没哟拿到bean这个对象

理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory,第4张

下面这个是getBean的根据名称拿一个类(注意:这个的获取规范是小驼峰),注意这个返回的是一个Object,所以我们需要对他进行类型转换

理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory,第5张

第三种:根据名称和类名拿

 public static void main(String[] args) {
        //启动类是帮助我们启动spring,这个命令可以返回一个spring
        //context上下文,就是spring一个运行环境
        ApplicationContext context=SpringApplication.run(IoCtryApplication.class, args);
        //从容器中拿对象
        UserController bean=context.getBean(UserController.class);
        //如果去掉Control注解,就会报错
        bean.prin();
        UserService bean2=context.getBean(UserService.class);
        bean2.doService();
        UserService bean3=(UserService) context.getBean("userService");
        bean3.doService();
        //根据名称和类型获取bean
        UserService userService=context.getBean("userService",UserService.class);
        userService.doService();
    }
}

⚠️特殊情况:假如类名前两位(第一位,第二位字母)都是大写的情况,bean的名称是类名理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory,第6张

常见面试题ApplicationContext   vs      BeanFactory

获取bean对象,是父类BeanFactory提供的功能

继承关系和功能方面来说:Spring容器有两个顶级的接口:BeanFactory和ApplicationContext.其中BeanFactory提供基础的访问容器能力,而ApplicationContext属于是BeanFactory的子类,他除了继承了BeanFactory的所有功能之外,他还拥有独特的特性,国际化支持(中日韩等语言)资源访问支持,以及事件传播等方面的支持

从性能方面来说:ApplicationContext是一次性加载并初始化所有的Bean对象,而BeanFactory是需要哪个就去加载哪个,因此会更加清量(空间与时间)

@Service(服务存储)和下面使用方法一致
@Repository(仓库存储)和control使用方法一致
@Repository
public class UserRepository {
    public void doRepository() {
        //代码格式化快捷键,crtl+alt+l
            System.out.println("aini");
        }
    }
 UserRepository userRepository=context.getBean(UserRepository.class);
        userRepository.doRepository();
@Component(组件存储)和下面用法一致
@Configuration(配置存储)
//        UserRepository userRepository=context.getBean(UserRepository.class);
//        userRepository.doRepository();
//        UserComponent userComponent=context.getBean(UserComponent.class);
//        userComponent.doComponent();
      UserConfig userConfig=context.getBean(UserConfig.class);
      userConfig.doConfig();
    }
package com.example.IOCtry.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfig {
    public void doConfig(){
        System.out.println("我也是条狗");
    }
}
为什么要去分层,假如说都用一个注解不行吗?-这就跟车牌号一样,方便管理,也节约号码

常见面试题二

常用的注解有哪些?分别是什么作用

web url映射:@RequestMapping

参数接口和接口响应:@RequestParam,@RequestBody,@ResponseBody

Bean的存储:@Controller,@Service,@Repository,@Component,@Configuration,@Bean

Bean的获取:@Autowired,@Qualifier,@Resource