Spring两个核心IoCDI(一)
目录👑
1、介绍
2、IoC详解
类注解:
方法注解:
3、BeanName
4、启动类路径
1、介绍
IoC(控制反转)和DI(依赖注入)可以理解为一个是存对象,一个是取对象
对象之前是谁使用谁去new一个对象,而IoC就是让spring去创建对象并存储起来,负责对象的初始化、依赖解析和生命周期管理,不需要我们自己再去创建,所以也可以说spring是一个IoC容器。而DI就是从spring容器中取出这个对象。
@Component
public class BookService {@Autowiredprivate BookDao bookDao;public List<BookInfo> getList() {// BookDao bookDao = new BookDao();List<BookInfo> bookInfos = bookDao.mockData();for(BookInfo bookInfo : bookInfos) {if(bookInfo.getStatus() == 2){bookInfo.setStatusCN("可借阅");}else{bookInfo.setStatusCN("不可借阅");}}return bookInfos;}
}
这里的@Component注解就表示把BookService对象交给Spring进行管理(存)
@RequestMapping("/book")
@RestController
public class BookController {@Autowiredprivate BookService bookService;@RequestMapping("/getList")public List<BookInfo> getList() {//BookService bookService = new BookService();List<BookInfo> bookInfos = bookService.getList();return bookInfos;}}
这里的@Autowired注解就表示从Spring中获取BookService对象并把这个对象赋值给bookService这个属性(取)
2、IoC详解
要把某个对象交给IoC容器进行管理有两类注解可以实现:
类注解:
@Controller, @Service, @Repository,@Component, @Configuration
@Controller, @Service, @Repository, @Configuration这4个都是@Component的衍生注解
@Controller:用于控制层,接收请求,对请求进行处理,并进行响应。
规范情况下,对外提供请求接口时,只能用@Controller注解
@Service:用于业务逻辑层,处理具体的业务逻辑
@Repository:用于数据访问层,也成为持久层,负责数据访问操作
@Configuration:配置层,处理项目中的一些配置信息
@Component:要将对象交给Spring IoC容器管理,又不归上面4个注解管的时候,就可以用@Component
方法注解:
@Bean,需要搭配五大注解使用,通常搭配@Component或@Configuration。
可以将方法的返回值作为存储在容器中的Bean,用于同一个类型需要定义多个对象存在IoC容器中或者是将第三方包中的对象放入IoC容器中 (因为我们无法直接修改第三方代码,就不能直接添加五大注解来将对象放入IoC容器中)。
3、BeanName
Bean就是IoC容器管理的特殊对象,beanName是唯一的,不重复的,类似于学生的学号,
beanName默认规则:
一、五大注解
1、类名的小驼峰写法(类名UserController,beanName名字userController)
2、类名前两位为大写时,beanName就是类名
二、@Bean注解(需要搭配五大注解使用,通常搭配@Component或@Configuration),
BeanName为方法名。
@Controller
public class UserController {public void sayHi() {System.out.println("UserController.sayHi");}
}
@SpringBootApplication
public class SpringIoCDemoApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(SpringIoCDemoApplication.class, args);//方式1UserController bean = context.getBean(UserController.class);bean.sayHi();//方式2UserController userController = (UserController)context.getBean("userController");userController.sayHi();//方式3UserController userController1 = context.getBean("userController", UserController.class);userController1.sayHi();}}
这三种方式获取的Bean对象都是相同的,一个是通过类来获取Bean,一个是通过beanName,一个是结合前两者。
@AllArgsConstructor
@Data
public class UserInfo {private Integer id;private String name;private Integer age;
}
@Configuration
public class UserInfoConfig {@Bean(name = {"user1","lisi"})public UserInfo user1() {UserInfo userInfo = new UserInfo(1,"lisi",15);return userInfo;}@Beanpublic UserInfo user2() {UserInfo userInfo = new UserInfo(2,"kiku",31);return userInfo;}
}
@Bean方法可以定义一个类型的不同Bean,用不同的方法名区分开
可以在@Bean的括号中添加name属性为BeanName重命名,因为它的name属性返回的是一个数组,因此可以设置一个或者多个BeanName
@Bean(name = "lisi"), @Bean(name = {"user1","lisi"})
同样五大注解也可以为BeanName重命名,比如@Configuration("c"),只能设置一个BeanName,不写属性名默认是赋值给value
@SpringBootApplication
public class SpringIoCDemoApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(SpringIoCDemoApplication.class, args);UserInfo userInfo1 = context.getBean("lisi",UserInfo.class);System.out.println(userInfo1);UserInfo userInfo11 = context.getBean("user1",UserInfo.class);System.out.println(userInfo11);UserInfo userInfo2 = context.getBean("user2",UserInfo.class);System.out.println(userInfo2);}}
通过上面的代码我们知道"lisi"和 "user1"都是给user1()这个方法返回的bean设置的beanName,所以userInfo1 和userInfo11获取的是同一个Bean,前面两个打出来一样。
4、启动类路径
默认情况下,spring只会扫描启动类所在的路径下的文件(有@SpringBootApplication注解的就是启动类)
package com.bit.springiocdemo;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringIoCDemoApplication {public static void main(String[] args) {
比如这个启动类的路径就是com.bit.springiocdemo,spring就只扫描这个路径下的内容。
可以通过@ComponentScan()这个注解来指定扫描路径,
比如我们把上面代码的路径改成com.bit
package com.bit.springiocdemo;import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;@ComponentScan(basePackages = "com.bit")
@SpringBootApplication
public class SpringIoCDemoApplication {public static void main(String[] args) {