全注解下的 spring IOC
BeanFactory 是一个顶层的接口,它的源码:
可以从IOC容器获取bean, 按类型或者名称获取bean;
默认bean都是单例存在;
ApplicationContext, BeanFactory的一个子接口;
大部分IOC容器都是ApplicationContext接口的实现类;
ApplicationContext接口在BeanFactory基础上,扩展了消息国际化接口(MessageSource),环境可配置接口(EnvironmentCapable),应用事件发布接口(ApplicationEventPublisher),资源模式解析接口(ResourcePatterResolver);
Spring boot使用注解装配bean 到IOC容器中去,而不是通过xml,
AnnotationConfigApplicationContext, 基于注解的IOC容器;
使用注解@Bean注入Spring Ioc容器中, 在一个配置java类中定义这些bean,然后这个类作为new AnnotationConfigApplicationContext()的参数,将定义的bean注入IOC容器中,但是这样主要一个个bean都使用@Bean注入,很麻烦;
但是spring允许扫描装配Bean 到IOC容器中,使用注解@Component, @ComponentScan , 前者表明哪个类扫描注入Spring IOC容器,后者表示何种策略去扫描装配Bean,
比如在loginServiceImpl类上面添加@Service注解,而在配置类(AppConfig)上面加上@ComponentScan注解;
在main中代码:
一般都是把这个注解直接加到springboot 的启动类上(这也是一个配置类);
@Service注解 是@Component的一个语义化的注解形式,本质还是@Component,
@ComponentScan允许我们自定义扫描的包,它的源码:
上面这些是它的常用配置项,basePackages定义扫描的包名,没有定义,就只扫描当前包,其子包下的路径;
excludeFilters 定义那些需要排除的Bean,比如有的时候模块不需要数据库相关的Bean,就需要使用到该配置项,否则的话没有进行数据库相关的配置,启动spring boot之后就会报错;
下面这个就说明了Service.class 虽然声明了@Service, 但是不装配它,不将其注入spring IOC容器中:
关于@SpringBootApplication:
它是一个组合注解,@Configuration + @EnableAutoConfiguration+@ComponentScan,它的源码:
下面是一般开发用的多的排除一些类的写法:
3.2 自定义第三方Bean
加入第三方包的类对象到 IOC容器中, @Bean注解;
例如引入DBCP数据源, 首先pom.xml 中加入所需的DBCP包,数据库Mysql驱动程序的依赖;
接着使用DBCP生成数据源,再将其放入AppConfig.java 中;
实际开发中用的多的其实是在application.properties中来声明数据源相关的配置,使用jdbc.properties 来声明具体的配置值;
3.3 依赖注入
使用注解@Autowired ,默认使用类型进行匹配Bean;by type;
但是当 type匹配到不止一个时,会报错, 比如注入的是Animal接口, 而其实现类有Dog, Cat,那么就会报错;
修改为:
根据属性名+Bean的名称来匹配;
当@Autowired 注解时,不能确定其标注的属性一定会存在,并允许这个被标注的属性为null, 可以配置如下:
@Autowired 除了标注属性外,还可以标注方法,以及标注方法的参数;
消除歧义性----@Primary和@Quelifier
上面的动物,和猫,狗的情况;
首先@Primary,优先权的注解,有猫有狗时,如果在猫类上加入这个注解,那么找到多个同类型的Bean时,会优先使用这个注解的类的实例;
但是多个类都可以标注这个注解, 猫和狗都标注,还是会不知道用哪个Bean,
这时使用@Quelifier,value需要一个字符串去定义,将与@Autowired组合到一起,通过类型和名称找到Bean;
上面的都基于一个默认情况,就是不带参数的构造方法实现依赖注入;
但是有的类只有有参数的构造方法,那上面的依赖注入方法就不可用了,
这时需要使用@Autowired注解对构造方法的参数进行注入,