@Bean注解
实例化对象到ioc容器中,等同于bean.xml中
@Scope注解 (scope : 范围)
用此注解来标注bean的使用范围 是单例还是多例
@Scope(“singletion”) 单例 默认为单例
IOC容器启动会调用方法创建bean对象放到ioc容器中,以后每次获取直接从ioc容器中拿
@Scope(prototype) 多例
IOC容器每次启动都不会去调用方法创建对象放到容器中,
而是每次用到 才会调用方法去创建对象,所以每次都新new一个对象,多例的对象都不相等
@Lazy 注解 (懒加载)
IOC容器启动时不会创建对象到容器,被调用后才会创建,而且单实例只会创建一次
@Condition注解 (条件)
根据条件选择性是否把bean注册到ioc容器中
给容器中注册组件的几种方式:
a, 通过@compentScan + 注解的方式 可以扫描到的bean都会实例化到IOC容器
也就是包扫描+注解(@Controller /@Service/@Repository…)
b,通过@Bean注解 (可导入第三方组件)
c,通过@Import注解 导入一个组件到ioc容器 (可导入第三方组件)
相对bean注解都可导入的区别在于import快速导入的方式更加快捷
d,通过spring的FactoryBean给容器注册bean (工厂bean,还可设置单例或多例)
@Import 注解(导入)
此注解只能用在类上,通过快读导入的方式实现把实例注册到IOC容器中
语法1: 直接填写class数组
@Import({ 类名.class , 类名.class… })
public class TestDemo {
}
语法2: 通过ImprotSelector方式
这种方式的前提是一个类要实现ImportSelector接口
创建Myclass类并且实现ImportSelector接口
public class Myclass implements ImportSelector {
//既然是接口肯定要实现这个接口的方法
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[0];
}
}
分析实现接口的selectImports方法中的:
a,返回值:就是我们实际上要导入到容器中的组件全类名
b,参数:AnnotationMetadata表示当前被@Import注解给标注的所有注解信息
语法3:通过ImportBeanDefinitionRegistrar方式
此方式从写registerBeanDefinitions 通过手动注册bean到容器中
@Bean的生命周期
bean创建—bean的初始化—bean销毁
容器管理bean的生命周期
我们可以自定义初始化和销毁的方法,容器在bean进行当前生命周期时来调用我们自定义的初始化和销毁方法,
构造(对象创建)
单实例:在容器启动的时候创建对象
多实例:在每次获取对象的时候创建对象
初始化:
对象创建完,并赋值好,调用初始化方法
销毁:
单实例:容器关闭对象销毁
多实例:容器不会管理多实例bean,容器也不会调用销毁方法;
ps:
public class Car {
public Car(){
System.out.println("car 无参构造。。。");
}
public void init(){
System.out.println("car init...");
}
public void destroy(){
System.out.println("car destroy");
}
}
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
return new Car();
}
自动装配:
spring通过依赖注入的方式来完成ioc容器中各个组件的依赖关系赋值;
1,通过@Autowire自动注入
1-1: 原理:默认优先按照类型的方式去容器中查找对应的组件,找到就赋值;
applicationContext.getBean(Car.class);
CarService{
@Autowire
private CarDao carDao;
}
1-2:如果查询到多个相同类型的组件;那么再将通过名称为id去容器中查询组件
applicationContext.getBean("carDao");
1-3: 通过 @Qualifier("carDao01")直接指定需要装配的组件id 而不是使用组件名