spring的生命周期
对于spring的生命周期,在宏观角度来看:
可以分为实例化前、实例化、实例化后、初始化前、初始化、初始化后。
在详细角度来看:
可以分为1.生成BeanDefinition 2.合并BeanDefinition 3.加载类 4.实例化前 5.推断构造方法 6.实例化
7.BeanDefinition的后置处理 8.填充属性 9.执行Aware(BeanNameAware、BeanClassLoadAware、BeanFactoryAware)
10.初始化前 (ApplicationContextAwareProcessor、InitDestoryAnnotationBeanPostProcessor) 11.初始化 12、初始化后。
==================================================
在讲生命周期之前,我们要先了解一下什么是BeanPostProcessor。他可以在bean的实例化、初始化前后加入自定义的一些逻辑。
可以从继承体系中看到,BeanPostProcessor有很多的接口被继承,我们可以将这些类分为三个功能。
我们可以拿BeanPostProcessor这个接口来验证,它是否是应用于初始化。
@Component public class WxyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("实例化之前UserService"); } return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("实例化后UserService"); } return null; } }
@Component public class UserService { public UserService() { System.out.println("实例化"); } }
这个例子其实并不能证明他是在初始化前后使用,但是能证明它是在实例化之后进行的。
=============================================================================================
接下来我们可以来讲spring的生命周期。
实例化前、后:
我们可以使用InstantiationAwareBeanPostProcessor接口来验证是否是在初始化前后调用。
@Component public class WxyBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("实例化之前"); } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("实例化之后"); } return false; } }
@Component public class UserService { public UserService() { System.out.println("实例化"); } }
从结果中可以看出来,确实是在实例化前后进行调用。
实例化:
@Component public class UserService { private User user; public UserService(){ System.out.println("无参数实例化"); } public UserService(User user){ System.out.println("1个参数实例化"); } }
调用的是无参数实例化
@Component public class UserService { private User user; public UserService(User user){ System.out.println("1个参数实例化"); } public UserService(User user,User user1){ System.out.println("2个参数实例化"); } }
因为没有指定,所以会报错
@Component public class UserService { private User user; public UserService(User user){ System.out.println("1个参数实例化"); } @Autowired public UserService(User user,User user1){ System.out.println("2个参数实例化"); } }
调用1个参数实例化的构造方法,因为进行了指定
@Component public class UserService { private User user; @Autowired public UserService(User user){ System.out.println("1个参数实例化"); } @Autowired public UserService(User user,User user1){ System.out.println("2个参数实例化"); } }
会报错,因为都进行了指定,系统不知道要选择哪个
@Component public class UserService { private User user; @Autowired(required = false) public UserService(User user){ System.out.println("1个参数实例化"); } @Autowired(required = false) public UserService(User user,User user1){ System.out.println("2个参数实例化"); } }
会调用2个参数的构造方法,因为required=false的意思表示非必要
@ComponentScan("wxy") public class Config { @Bean public User user(){ return new User(); } @Bean public User user1(){ return new User(); } }
@Component public class UserService { private User user; public UserService(User user){ System.out.println("1个参数实例化"); } @Autowired(required = true) public UserService(User user,User user1){ System.out.println("2个参数实例化"); } }
会调用2个参数实例化的构造方法,Autowired是先找类型,找到类型之后数量有多个,则开始找名字相同的。
@ComponentScan("wxy") public class Config { @Bean public User user(){ return new User(); } @Bean public User user2(){ return new User(); } }
@Component public class UserService { private User user; public UserService(User user){ System.out.println("1个参数实例化"); } @Autowired(required = true) public UserService(User user,User user1){ System.out.println("2个参数实例化"); } }
这样会报错,因为容器中有user、user2的bean,然后构造方法中有user1这是没有的。
============================================================
实例化后:
@Component public class BeanPostProcessor1 implements InstantiationAwareBeanPostProcessor { //实例化前 @Override public Object postProcessBeforeInstantiation(Class<?> aClass, String beanName) throws BeansException { return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if(beanName.equals("userService")){ System.out.println("实例化后-----"); } return true; } }
这个是实现InstantiationAwareBeanPostProcessor 类的方法,postProcessAfterInstantiation是实例化后的方法,注意到它的返回值是boolean,false表示实例化后不需要走spring的属性注入,如果是true表示还需要属性注入。
@Component public class UserService { private User user; @Autowired public void aaa(User user){ System.out.println("set注入"); this.user = user; } }
@Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if(beanName.equals("userService")){ System.out.println("实例化后-----"); } return false; }
=================================
初始化
初始化的方式有2种,一种是实现InitializingBean接口的afterPropertiesSet方法,这个方法是在属性注入之后调用,一般用来做校验。
方式1:
@Component public class UserService implements InitializingBean { private User user; public UserService() { System.out.println("实例化"); } @Autowired public void setUser(User user) { System.out.println("属性注入:set方法注入"); this.user = user; } // @PostConstruct // public void xxx(){ // System.out.println("初始化方式1"); // } @Override public void afterPropertiesSet() throws Exception { System.out.println("初始化方式2"); } }
@Component public class WxyBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("实例化之前"); } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("实例化之后"); } return true; } //BeanPostProcess的实现方法---初始化之后 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("初始化之前"); } return bean; }
//BeanPostProcess的实现方法---初始化之前
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("初始化之后"); } return null; } }
通过结果能看到结果打印“初始化方式2”。
方式2:通过使用注解@PostConstruct进行初始化,但是有一个责任链模式,如果初始化前的postProcessBeforeInitialization方法返回值是bean,那么被注解@PostConstruct修饰的方法则可以运行,如果方法返回值是null,则不执行该方法。
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency>
@Component public class UserService implements InitializingBean { private User user; public UserService() { System.out.println("实例化"); } @Autowired public void setUser(User user) { System.out.println("属性注入:set方法注入"); this.user = user; } @PostConstruct public void xxx(){ System.out.println("初始化方式1"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("初始化方式2"); } }
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("初始化之前"); } return null; }
可以从结果看到,“初始化方法1”没有打印,说明xxx方法没有被执行。
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("userService")){ System.out.println("初始化之前"); } return bean; }
可以从结果看到,“初始化方法1”有打印,说明xxx方法被执行。