Day05-12.分层解耦-IOC&DI-IOC详情
1.IOC控制反转详解:
1.所谓控制反转,指的就是将对象的控制权交给IOC容器,由IOC容器来创建及管理这些对象,而IOC容器当中的这写对象也称为Bean对象。
在刚才的入门程序当中,我们直接在类上加了一个注解Component皆可以来声明一个bean对象。
2.在Spring框架当中,除了Component这个注解以外,Spring框架为了更好的标识web应用程序开发当中bean对象到底归属哪一层,又提供了Component的三个衍生注解。分别是@Controller,@Service,@Repository,这三个注解分别用来表示Controller层的bean对象,Service层的bean对象,以及Repository层的bean对象。我们现在如果去定义Service层以及Dao层的bean对象,我们可以通过Component注解,也可以通过Service以及repository这些注解。但是在web程序的开发当中,推荐使用这三个衍生注解来标注Controller、Service、以及Dao层的Bean。
3.那Component注解什么时候用呢??
如果在项目开发当中,某一个类不能归属到这三层里面,我们还想将这个类交给IOC容器管理,我们就可以使用component注解,最典型的就是一些工具类。
注解 说明 位置
@Component 声明bean的基础注解 不属于以下三类时,用此注解
@Controller @Component的衍生注解 标注在控制器类上
@Service @Component的衍生注解 标注在业务类上
@Repository @Component的衍生注解 标注在数据访问类上(由于与mybatis整合,用得少)
4.现在我们声明一个bean就可以通过四个注解来声明,而在IOC容器当中,每一个bean他都有一个标识,也就是bean的名字,在声明bean的时候,我们可以通过注解当中的value这个属性来指定这个bean的名字。如果说我们没有指定这个value属性,这个bean也是有名字的,默认是类名首字母小写。如果要指定,像这样:@Repository(value = “daoA”)就可以了。这个value可写可不写:@Repository(“daoA”),一般不指定,用默认值。
IDEA里面提供了一个面板Endpoints,点击一下,进去过后,第一栏展示的就是beans,展示的就是当前这个应用下所有的bean对象。点击application,右侧就会展示出很多的bean对象,白色背景的是我们自己定义的,点击EmpController,右侧展示的就是这个bean的名字,会看到首字母小写了。
注意事项:
1.声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
2.使用以上四个注解都可以声明bean对象,但是在springBoot集成web开发中,声明控制器bean只能用@Controller。
2.Bean组件扫描:
1.前面声明bean的四大注解,要想生效,还需要被组件扫描注解@ComponentScan扫描。
@ComponentScan注解是Spring框架当中提供的,用来扫描那四个注解的。
2.@ComponentScan注解虽然没有显示配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication中,
默认扫描的范围是启动类所在包及其子包。
@SpringBootApplication这个注解包含了@ComponentScan注解的功能
@SpringBootApplication默认扫描当前包及其子包,当前包指的就是启动类当前所在的包,子包就是启动类所在包的子包。
所以如果把代码放在启动类所在包的外面,那这个bean就扫描不上了,扫描不上就不会生效了。
3.要想解决这个问题??
第一种方案:需要手动在这一块去指定一下@ComponentScan手动的来设置包扫描,@ComponentScan({“dao”,“com.itheima”})
@ComponentScan({"Dao", "com.itheima.springbootwebreqresp"})
//如果声明了这个注解,下面的注解就没用了,所以要把其他要扫描的包加上
@SpringBootApplication
//默认扫描当前包及其子包
这种方法可以,但是不推荐。
第二种方案:按照SpringBoot项目的规范,将我们所写的代码全部放在启动类所在包及其子包下,这样SpringBoot项目在启动的时候就会自动扫描到这些bean对象。非常推荐。
3.小结:
1.声明bean的注释
1.@Component,@Controller,@Service,@Repository
2.@SpringBootApplication具有包扫描的作用,默认扫描当前包及其子包。