Spring IoC(2)
1.Bean的存储
Spring中有两类注解可以实现把某个对象交给IoC容器管理
(1).类注解:@Contorller @Service @Repository @Component @Configuration
(2).方法注解:@Bean
下面是对这些注解的详细解释:
类注解
1.@Controller(控制器注解),下面是一个使用@Controller存储bean的代码
可以看到可以使用这个类中的方法了.ApplicationContext,即Spring上下文.因为对象都交给Spring管理了,所以获取对象要从Spring中获取,就得先得到Spring的上下文.如果把@Controller删除,再运行程序,会抛出下面的异常.报错显示:找不到这个类型的bean.
除了这个方式之外,还有别的方式来获取bean对象.还可以根据bean的名称来获取bean对象.那么什么是bean名称呢?Spring bean是Spring框架再运行时管理的对象,Spring会给管理的对象起一个名字,根据bean的名称就可以获取到对应的对象.bean命名规以小写字母开头,然后使用驼峰式大小写.如,UserController,bean的名称为userController. AccountService,bean的名称为 accountServcie.除了这种常见的命名之外,如果类名为UController,则bean的名称为 UController.
根据bean的名称来获取bean
这里可以看到运行结果是一样的,说明这三种方法获取到的bean是同一个.
ApplicationContext和BeanFactory
继承和功能反面来说:Spring容器有两个顶级的接口:BeanFactory和ApplicationContext.其中BeanFactory提供了基础的访问容器的能力,而ApplicationContext属于BeanFactory的子类,除了继承BeanFactory的所有功能之外,还拥有独特的功能,添加了对国际化,资源访问支持,以及事件传播等方面的支持.性能方面,ApplicationContext是一次性加载并初始化所有的bean对象,而BeanFactory是需要那个才去加载那个,因此更加轻量.
2.@Service(服务存储)
可以成功使用这个方法
3.@Repository(仓库存储)
4.@Component(组件注解)
5.@Configuration(配置存储)
为什么要有这么多的类注解?
这与应用分层有关,当看见注解之后,可以了解到当前类的用途.
@Controller:控制层,接受请求,对请求进行处理,并进行响应.
@Service: 业务逻辑层,处理具体的业务逻辑.
@Repository:数据访问层,也称为持久层,负责数据访问.
@Configuration:配置层,处理项目中的一些配置信息.
程序进行应用分层之后,调用流程如下:
@Controller,@Service,@Repository都是@Component注解的衍生注解.
@Controller,@Service,@Repository用于更具体的用例.
方法注解@Bean
类注解是添加在类上的,但是存在问题:使用外部包的类,没办法添加类注解.一个类,需要多个对象.这两种问题,只使用类注解是无法完成的.因此就需要方法注解.
方法注解@Bean:在Spring中,方法注解需要搭配类注解,才能将对象存储到Spring容器中.
如果定义多个对象,该如何获取呢?
这样运行程序会报如下错误.显示:期望只有一个匹配,结果发现了两个user1,user2.使用方法名获取bean即可,
@Bean可以针对同一个类,定义多个对象.
可以通过设置name的属性给Bean对象进行重命名操作.
其中,name=可以省略.
只有一个名称时,{}也可以省略.
扫描路径
上面两种路径中,第一种会发生错误,原因是默认的扫描路径是SpringBoot启动类所在包及其子包.因此第一种,Spring容器中没有相关的bean.推荐使用第二种目录,将DemoApplication类放在最外部.
DI详解
依赖注入是一个过程,是指IoC容器在创建Bean时,去提供运行时所依赖的资源,而资源指的就是对象,即把对象取出来放到某个类的属性中.Spring中有三种依赖注入的方式.
1.属性注入
属性注入是使用@Autowired实现的.
可以看到正确运行了.
2.构造方法注入
如果类只有一个构造方法,那么@Autowired注解可以省略;如果类中有多个构造方法,那么需要添加上@Autowired来明确到底使用那个构造方法.
3.Setter注入
Setter注入和属性的Setter方法实现类似,需要在设置set方法的时候需要加上@Autowired注解.
属性注入:优点,简洁方便.缺点,只能用于IoC容器,如果是非IoC容器不可用,并且只有在使用的时候才会出现NPE(空指针异常),不能注入一个Final修饰的属性.构造函数注入: 优点,可以注入final修饰的属性,注入的对象不会被修改.依赖对象在使用前一定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行的方法.通用性好.构造犯法是JDK支持的,所以更换任何框架,都是使用的.缺点:注入多个对象时,代码会比较繁琐. Setter注入:优点,方法在类实例之后,重新对该对象进行配置或者注入.缺点:不能注入一个Final修饰的属性.注入对象可能被改变,因为setter方法可能被多次调用,就有被修改的风险.
@Autowired存在的问题:当同一类型存在多个bean时,使用@Autowired会存在问题.
报错的原因是,非唯一的Bead对象.如何解决上述问题?Spring提供了一下几种解决方案.
1.使用@Primary注解:当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认实现.
使用@Qualifier注解,指定当前要注入的bean对象.并且要指定注入的bean名称
使用@Resource注解:是按照bean的名称进行注入.通过name属性指定要注入的bean的名称.
@Autowired与@Resource的区别
@Autowired时Spring框架提供的注解,@Resource是JDK提供的注解
@Autowired默认是按照类型注入,而@Resoure是按照名称注入.相比于@Autowired来说,@Resource支持更多的参数类型,例如name设置,根据名称获取Bean.