【Spring注解】——生命周期以及自动装配

    本文主要讲解一下配合spring注解讲解spring中bean的生命周期和自动装配涉及到一些注解,如有理解偏颇之处,恳请各位大神指正。

容器管理bean的生命周期

bean的生命周期

     bean创建——初始化——销毁过程

--> Spring IOC容器实例化Bean
--> 调用BeanPostProcessor的postProcessBeforeInitialization方法
--> 调用bean实例的初始化方法
--> 调用BeanPostProcessor的postProcessAfterInitialization方法

BeanPOstProcessor原理

 * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
 * initializeBean
 * {
 * applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 * invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
 * applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *}

1、构造(对象创建)

    @Scope

      单实例:在容器启动的时候创建对象

      多实例:在每次获取的时候创建对象

2、初始化

     对象创建完成,并赋值好,调用初始化方法。

1)通过@Bean指定init-method和destroy-method

@Bean(initMethod="init",destroyMethod="detory")
public Car car(){
   return new Car();
}

2)通过实现让bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑);

@Component
public class Cat implements InitializingBean,DisposableBean {
	
	public Cat(){
		System.out.println("cat constructor...");
	}

	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("cat...destroy...");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("cat...afterPropertiesSet...");
	}
}

3)使用JSR520:

@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法

@PreDestroy:在容器销毁bean之前通知我们进行清理工作

@Component
public class Dog{
	public Dog(){
		System.out.println("dog constructor...");
	}
	//对象创建并赋值之后调用
	@PostConstruct
	public void init(){
		System.out.println("Dog....@PostConstruct...");
	}
	//容器移除对象之前
	@PreDestroy
	public void detory(){
		System.out.println("Dog....@PreDestroy...");
	}
}

4)自定义实现BeanPostProcessor接口的bean后置处理器

在bean初始化前后进行一些处理工作;可以用来处理初始化前后的方法

 * postProcessBeforeInitialization:在初始化之前工作
 * postProcessAfterInitialization:在初始化之后工作
Demo展示
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

	//初始化之前
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
		return bean;
	}

	//初始化之后
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
		return bean;
	}
}

2、属性赋值

1)@Value

1、基本数值
2、可以写SpEL; #{}

3、可以写${};取出配置文件【properties】中的值(在运行环境变量里面的值)

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

注意:如果需要给静态成员变量赋值,上述赋值为null,因为static是在bean初始化之前进行赋值的,所以@value无法赋值,具体解决方案,详见https://blog.csdn.net/jiadajing267/article/details/79715231

2)@PropertySource

使用@PropertySource读取外部配置文件中的k/v保存到运行的环境变量中;加载完外部的配置文件以后使用${}取出配置文件的值

3、自动装配

1)、@Autowired 自动注入

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

@Autowired:标注在构造器,参数,方法,属性;都是从容器中获取参数组件的值

2)@Resource

    可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;

    没有能支持@Primary功能没有支持@Autowired(reqiured=false);

3)@Inject

     需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能

     @Autowired是spring定义,@Resource和@Inject是Java规范

4、自定义组件获取spring容器底层组件

自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);
自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;

把Spring底层一些组件注入到自定义的Bean中

 * xxxAware:功能使用xxxProcessor;
 * 	ApplicationContextAware==》ApplicationContextAwareProcessor;
Demo
@Component
public class Dog implements ApplicationContextAware {
	//@Autowired
	private ApplicationContext applicationContext;
	
	public Dog(){
		System.out.println("dog constructor...");
	}
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// TODO Auto-generated method stub
		this.applicationContext = applicationContext;
	}
}

5、根据环境装配bean

@Profile

    Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;最常见的就是利用swagger的使用问题

 1)、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
 2)、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
 3)、没有标注环境标识的bean在,任何环境下都是加载的

猜你喜欢

转载自blog.csdn.net/jiadajing267/article/details/81045292