Spring中@Bean的生命周期和@Value赋值的理解

@Bean的生命周期
bean创建—初始化—销毁
容器管理bean的生命周期
我们可以自定义初始化和销毁方法;容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
构造(对象创建)
单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象

初始化:
对象创建完成,并赋值好,调用初始化方法
销毁:
容器关闭的时候销毁

1.指定初始化和销毁方法;
以前基于配置,有init-method、destory-method属性去配置方法,方法必须没有参数,但是可以抛任何异常

public class Car{
    public Car(){
    }
    
    public void init(){}

    public void destory(){}
}

@Configuration
public class MyConfig{
    @Bean
    public Car car{
        return new Car();
    }
}

现在通过@Bean指定init-method、destory-method
2.通过让Bean实现InitializingBean接口(定义初始化逻辑)
DisposableBean接口(定义销毁逻辑)

@Component
public class Cat implements InitializingBean, DisposableBean {
    public Cat(){}
    //在容器关闭的时候进行调用
    @Override
    public void destroy() throws Exception {

    }
    //在Bean创建完成,并且属性都赋值好后调用
    @Override
    public void afterPropertiesSet() throws Exception {

    }
}

3.@PostConstruct和@PreDestory;使用JSR250
@PostConstruct:在bean创建完成并且属性赋值好后,来执行初始化方法;标注在方法上
@PreDestory:在容器销毁bean之前通知我们进行清理工作

public class Dog{
    public Dog(){}

    //对象创建并赋值后调用
    @PostConstruct
    public void init(){}

    //容器移除对象之前调用
    @PreDestory
    public void destory(){}
}

4.BeanPostProcessor接口:bean的后置处理器
在bean初始化前后进行一些处理工作
postProcessBeforeInitialization:初始化之前进行后置处理工作
postProcessAfterInitialization:初始化之后进行后置处理工作
Spring底层对BeanPostProcessor的使用:
bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async,XXX等等的功能,都是通过BeanPostProcessor来完成的

@Value赋值
1.基本数值
2.可以写SpEL;#{}
3.可以写 使 @ P r o p e r t y S o u r c e K / V 使 {};取出配置文件(运行环境变量)中的值 先使用@PropertySource读取外部配置文件中的K/V保存到运行环境变量中;加载完外部的配置文件以后使用 {}取出配置文件的值

@PropertySource(value={"classpath:/person.properties"})
@Configuration
public class MainConfigOfPropertyValues{
    @Bean
    public Person person(){
        return new Person();
    }
}

public class Person{
    @Value("张三")
    private String name;
    @Value("#{20-2}")
    private Integer age;
    @Value("${person.nickName}")
    private String nickName;
}

person.properties文件内容
person.nickName=......

自动装配:
Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值;
1.@Autowired:自动注入
1).默认优先按照类型去容器中找对应的组件:applicationContext.getBean(BookDao.class);
2).如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
applicationContext.getBean(“bookDao”);
3).@Qualifier(“bookDao”):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
4).自动装配默认一定要将属性赋值好,没有就会报错;
5).@Primary:让Spring进行自动装配的时候,默认会使用首选的bean;
也可以继续使用@Qualifier指定需要装配的bean的名字

2.Spring还支持使用@Resource(JSR250)和@Inject(JSR330)【Java规范的注解】
@Resource:可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的
@Resource(name=“bookDao2”)
没有支持@Primary功能,没有支持@Autowired(require=“false”);
@Inject:要使用此注解需要导入依赖,javax.inject,和Autowired的功能一样,但是没有require=false的功能

@Autowired是Spring定义的,而@Resource和@Inject是Java的规范
3.@Autowired:可以标注在构造器、参数、方法、属性上;都是从容器中获取参数组件的值
1)标注在方法上:Spring容器创建当前对象,就会调用方法,完成赋值;方法使用的参数,自定义类型的值从ioc容器中进行获取

@Autowired
public void setCar(Car car){
    this.car = car;
}

@Bean标注的方法创建对象的时候,方法参数的值从容器中获取

@Bean
public Color color(Car car){    //car从容器中获取
    Color color = new Color();
    color.setCar(car);
    return color;
}

默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
构造器要用的组件、参数,也是从容器中获取的
2)标注在构造器:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取
3)放在参数位置;

4.自定义组件想要使用Spring容器底层的一些组件(ApplicationContext、BeanFactory、XXX)
自定义组件实现XXXAware接口:在创建对象的时候,会调用接口规定的方法注入相关组件;参照Aware接口设计
把Spring底层一些组件注入到自定义的Bean中;
XXXAware的功能是使用XXXProcessor(后置处理器)来实现的;
ApplicationContextAware===>ApplicationContextAwareProcessor

猜你喜欢

转载自blog.csdn.net/mrcool2012/article/details/104667676