• 深入浅出Spring(23)


    参考链接1

    Spring bean生命周期

    1. 阶段1:Bean元信息配置阶段
    2. 阶段2:Bean元信息解析阶段
    3. 阶段3:将Bean注册到容器中
    4. 阶段4:BeanDefinition合并阶段
    5. 阶段5:Bean Class加载阶段
    6. 阶段6:Bean实例化阶段
    7. 阶段7:合并后的BeanDefinition处理
    8. 阶段8:属性赋值阶段
    9. 阶段9:Bean初始化阶段
    10. 阶段10:所有单例bean初始化完成后阶段
    11. 阶段11:Bean的使用阶段
    12. 阶段12:Bean销毁前阶段
    13. 阶段13:Bean销毁阶段

    阶段6分为

    1. Bean实例化前阶段
    2. Bean实例化阶段

    阶段8分为

    1. Bean实例化后阶段
    2. Bean属性赋值前阶段.
    3. Bean属性赋值阶段

    阶段9分为

    1. Bean Aware接口回调阶段
    2. Bean初始化前阶段
    3. Bean初始化阶段
    4. Bean初始化后阶段

    阶段1:Bean元信息配置阶段

    Bean信息定义4种方式

    主要包括xml,@Bean,properties文件,接口

    接口

    案例1:组装一个简单的bean

    public class Car {
        private String name;
    	//省略get、set、toStirng
    }
    
    • 1
    • 2
    • 3
    • 4
    public class Client {
        public static void main(String[] args) {
            BeanDefinitionBuilder beanDefinitionBuilder = 
            BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
            BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
            System.out.println(beanDefinition);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出

    Root bean: class [com.example.lurenjia.spring.c22.d1.Car];
    scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0;
    autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null;
    initMethodName=null; destroyMethodName=null
    
    • 1
    • 2
    • 3
    • 4

    案例2:组装一个有属性的bean

    public class Client2 {
        public static void main(String[] args) {
            BeanDefinitionBuilder beanDefinitionBuilder = 
            BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
            beanDefinitionBuilder.addPropertyValue("name", "奥迪");
            BeanDefinition carBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
            System.out.println(carBeanDefinition);
            System.out.println("----");
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            factory.registerBeanDefinition("car", carBeanDefinition);
            Car bean = factory.getBean("car", Car.class);
            System.out.println(bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出

    Root bean: class [com.example.lurenjia.spring.c22.jd1.d1.Car]; scope=; abstract=false; lazyInit=null;
     autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; 
     factoryMethodName=null; initMethodName=null; destroyMethodName=null
    ----
    Creating shared instance of singleton bean 'car'
    Car{name='奥迪'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    案例3:组装一个有依赖关系的bean

    public class User {
    
        private String name;
    
        private Car car;
    	//省略get、set、toStirng
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class Client3 {
        public static void main(String[] args) {
            BeanDefinition carBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName()).addPropertyValue("name", "奥迪").getBeanDefinition();
            BeanDefinition userBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName()).
                    addPropertyValue("name", "路人甲Java").
                    addPropertyReference("car", "car").
                    getBeanDefinition();
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            factory.registerBeanDefinition("car", carBeanDefinition);
            factory.registerBeanDefinition("user", userBeanDefinition);
            System.out.println(factory.getBean("car"));
            System.out.println(factory.getBean("user"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    Car{name='奥迪'}
    User{name='路人甲Java', car=Car{name='奥迪'}}
    
    • 1
    • 2

    案例4:来2个有父子关系的bean

    public class Client4 {
        public static void main(String[] args) {
            BeanDefinition carBeanDefinition1 = BeanDefinitionBuilder.
                    genericBeanDefinition(Car.class).
                    addPropertyValue("name", "保时捷").
                    getBeanDefinition();
    
            BeanDefinition carBeanDefinition2 = BeanDefinitionBuilder.
                    genericBeanDefinition().
                    setParentName("car1").
                    getBeanDefinition();
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            factory.registerBeanDefinition("car1", carBeanDefinition1);
            factory.registerBeanDefinition("car2", carBeanDefinition2);
            System.out.println(String.format("car1->%s", factory.getBean("car1")));
            System.out.println(String.format("car2->%s", factory.getBean("car2")));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    car1->Car{name='保时捷'}
    car2->Car{name='保时捷'}
    
    • 1
    • 2

    案例5:通过api设置(Map、Set、List)属性

    public class CompositeObj {
    
        private String name;
        private Integer salary;
    
        private Car car1;
        private List<String> stringList;
        private List<Car> carList;
    
        private Set<String> stringSet;
        private Set<Car> carSet;
    
        private java.util.Map<String, String> stringMap;
        private java.util.Map<String, Car> stringCarMap;
    
        //省略get set tostring
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class Client {
        public static void main(String[] args) {
            //定义car1
            BeanDefinition car1 = BeanDefinitionBuilder.
                    genericBeanDefinition(Car.class).
                    addPropertyValue("name", "奥迪").
                    getBeanDefinition();
            //定义car2
            BeanDefinition car2 = BeanDefinitionBuilder.
                    genericBeanDefinition(Car.class).
                    addPropertyValue("name", "保时捷").
                    getBeanDefinition();
    
            //定义CompositeObj这个bean
            //创建stringList这个属性对应的值
            ManagedList<String> stringList = new ManagedList<>();
            stringList.addAll(Arrays.asList("java高并发系列", "mysql系列", "maven高手系列"));
    
            //创建carList这个属性对应的值,内部引用其他两个bean的名称[car1,car2]
            ManagedList<RuntimeBeanReference> carList = new ManagedList<>();
            carList.add(new RuntimeBeanReference("car1"));
            carList.add(new RuntimeBeanReference("car2"));
    
            //创建stringList这个属性对应的值
            ManagedSet<String> stringSet = new ManagedSet<>();
            stringSet.addAll(Arrays.asList("java高并发系列", "mysql系列", "maven高手系列"));
    
            //创建carSet这个属性对应的值,内部引用其他两个bean的名称[car1,car2]
            ManagedList<RuntimeBeanReference> carSet = new ManagedList<>();
            carSet.add(new RuntimeBeanReference("car1"));
            carSet.add(new RuntimeBeanReference("car2"));
    
            //创建stringMap这个属性对应的值
            ManagedMap<String, String> stringMap = new ManagedMap<>();
            stringMap.put("系列1", "java高并发系列");
            stringMap.put("系列2", "Maven高手系列");
            stringMap.put("系列3", "mysql系列");
    
            ManagedMap<String, RuntimeBeanReference> stringCarMap = new ManagedMap<>();
            stringCarMap.put("car1", new RuntimeBeanReference("car1"));
            stringCarMap.put("car2", new RuntimeBeanReference("car2"));
    
    
            //下面我们使用原生的api来创建BeanDefinition
            GenericBeanDefinition compositeObj = new GenericBeanDefinition();
            compositeObj.setBeanClassName(CompositeObj.class.getName());
            compositeObj.getPropertyValues().add("name", "路人甲Java").
                    add("salary", 50000).
                    add("car1", new RuntimeBeanReference("car1")).
                    add("stringList", stringList).
                    add("carList", carList).
                    add("stringSet", stringSet).
                    add("carSet", carSet).
                    add("stringMap", stringMap).
                    add("stringCarMap", stringCarMap);
    
            //将上面bean 注册到容器
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            factory.registerBeanDefinition("car1", car1);
            factory.registerBeanDefinition("car2", car2);
            factory.registerBeanDefinition("compositeObj", compositeObj);
    
            //下面我们将容器中所有的bean输出
            for (String beanName : factory.getBeanDefinitionNames()) {
                System.out.println(String.format("%s->%s", beanName, factory.getBean(beanName)));
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="helloWorld" class="com.example.lurenjia.spring.c3.HelloWorld"/>
    
    </beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    xml中的bean配置信息会被解析器解析为BeanDefinition对象,一会在第二阶段详解。

    properties文件的方式

    参照阶段2解析里面properties文件定义内容

    注解的方式

    类上标注@Compontent注解来定义一个bean

    示例省略

    配置类中使用@Bean注解来定义bean

    示例省略

    阶段2:Bean元信息解析阶段

    目的:将阶段1各种方式的定义解析为 BeanDefinition 对象

    XML方式解析:XmlBeanDefinitionReader

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
           
        <bean id="helloWorld" class="com.example.lurenjia.spring.c3.HelloWorld"/>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    public class Client {
        public static void main(String[] args) {
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
            String location = "classpath:beans3.xml";
            int countBean = xmlBeanDefinitionReader.loadBeanDefinitions(location);
            System.out.println(String.format("共注册了 %s 个bean", countBean));
            for (String beanName : factory.getBeanDefinitionNames()) {
                BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
                String beanDefinitionClassName = beanDefinition.getClass().getName();
                Object bean = factory.getBean(beanName);
                System.out.println(beanName + ":");
                System.out.println("    beanDefinitionClassName:" + beanDefinitionClassName);
                System.out.println("    beanDefinition:" + beanDefinition);
                System.out.println("    bean:" + bean);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    共注册了 1 个bean
    helloWorld:
        beanDefinitionClassName:org.springframework.beans.factory.support.GenericBeanDefinition
        beanDefinition:Generic bean: class [com.example.lurenjia.spring.c3.HelloWorld]; scope=; abstract=false; 
        lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; 
        factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; 
        defined in class path resource [beans3.xml]
        bean:com.example.lurenjia.spring.c3.HelloWorld@51565ec2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    properties文件定义bean的解析:PropertiesBeanDefinitionReader

    官方示例

       employee.(class)=MyClass       // bean is of class MyClass
       employee.(abstract)=true       // this bean can't be instantiated directly
       employee.group=Insurance       // real property
       employee.usesDialUp=false      // real property (potentially overridden)
      
       salesrep.(parent)=employee     // derives from "employee" bean definition
       salesrep.(lazy-init)=true      // lazily initialize this singleton bean
       salesrep.manager(ref)=tony     // reference to another bean
       salesrep.department=Sales      // real property
      
       techie.(parent)=employee       // derives from "employee" bean definition
       techie.(scope)=prototype       // bean is a prototype (not a shared instance)
       techie.manager(ref)=jeff       // reference to another bean
       techie.department=Engineering  // real property
       techie.usesDialUp=true         // real property (overriding parent value)
      
       ceo.$0(ref)=secretary          // inject 'secretary' bean as 0th constructor arg
       ceo.$1=1000000                 // inject value '1000000' at 1st constructor arg
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    我们在resource目录下创建一个beans.properties

    car.(class)=com.example.lurenjia.spring.c22.jd1.d1.Car
    car.name=name1
    
    car1.(class)=com.example.lurenjia.spring.c22.jd1.d1.Car
    car1.name=name2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class Client {
        public static void main(String[] args) {
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            PropertiesBeanDefinitionReader propertiesBeanDefinitionReader = new PropertiesBeanDefinitionReader(factory);
            String location = "classpath:beans.properties";
            int countBean = propertiesBeanDefinitionReader.loadBeanDefinitions(location);
            System.out.println(String.format("共注册了 %s 个bean", countBean));
            for (String beanName : factory.getBeanDefinitionNames()) {
                BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
                String beanDefinitionClassName = beanDefinition.getClass().getName();
                Object bean = factory.getBean(beanName);
                System.out.println(beanName + ":");
                System.out.println("    beanDefinitionClassName:" + beanDefinitionClassName);
                System.out.println("    beanDefinition:" + beanDefinition);
                System.out.println("    bean:" + bean);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    注解方式:PropertiesBeanDefinitionReader

    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Primary
    @Lazy
    public class Service1 {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class Service2 {
    
        @Autowired
        private Service1 service1;
    
        @Override
        public String toString() {
            return "Service2{" +
                    "service1=" + service1 +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    public class Client {
        public static void main(String[] args) {
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(factory);
            annotatedBeanDefinitionReader.register(Service1.class, Service2.class);
            for (String beanName : new String[]{"service1", "service2"}) {
                BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
                String beanDefinitionClassName = beanDefinition.getClass().getName();
                Object bean = factory.getBean(beanName);
                System.out.println(beanName + ":");
                System.out.println("    beanDefinitionClassName:" + beanDefinitionClassName);
                System.out.println("    beanDefinition:" + beanDefinition);
                System.out.println("    bean:" + bean);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述
    这里为什么会输出一个null呢

    在 for 循环上面添加一行代码

            factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);
    
    • 1

    在这里插入图片描述

    阶段3:Spring Bean注册阶段

    一个重要的接口 BeanDefinitionRegistry

    BeanDefinitionRegistry源码

    public interface BeanDefinitionRegistry extends AliasRegistry {
    	//注册bean定义
    	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    			throws BeanDefinitionStoreException;
    	//移除bean定义
    	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
    	//获取bean定义
    	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
    	//是否包含bean定义
    	boolean containsBeanDefinition(String beanName);
    	//获取bean定义名称
    	String[] getBeanDefinitionNames();
    	//获取bean定义数量
    	int getBeanDefinitionCount();
    	//beanName是否已经注册
    	boolean isBeanNameInUse(String beanName);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    AliasRegistry

    AliasRegistry 是 BeanDefinitionRegistry 的父接口

    public interface AliasRegistry {
    	//注册别名
    	void registerAlias(String name, String alias);
    	//移除别名
    	void removeAlias(String alias);
    	//判断是不是别名
    	boolean isAlias(String name);
    	//获取别名数组
    	String[] getAliases(String name);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    BeanDefinitionRegistry实现类

    DefaultListableBeanFactory

    public class Client {
        public static void main(String[] args) {
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            GenericBeanDefinition nameBdf = new GenericBeanDefinition();
            nameBdf.setBeanClass(String.class);
            nameBdf.getConstructorArgumentValues().addIndexedArgumentValue(0, "abcdefg");
            factory.registerBeanDefinition("name", nameBdf);
            System.out.println(factory.getBeanDefinition("name"));
            System.out.println(factory.containsBeanDefinition("name"));
            System.out.println(Arrays.asList(factory.getBeanDefinitionNames()));
            System.out.println(factory.getBeanDefinitionCount());
            System.out.println(factory.isBeanNameInUse("name"));
            factory.registerAlias("name", "alias-name-1");
            factory.registerAlias("name", "alias-name-2");
            System.out.println(factory.isAlias("alias-name-1"));
            System.out.println(Arrays.asList(factory.getAliases("name")));
            System.out.println(factory.getBean("name"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    Generic bean: class [java.lang.String]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
    true
    [name]
    1
    true
    true
    [alias-name-2, alias-name-1]
    10:25:45.492 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'name'
    abcdefg
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    阶段4:BeanDefinition合并阶段

    目的:

    案例

    public class LessonModel {
    
        private String name;
    
        private int lessonCount;
    
        private String description;
        //省略get set tostring
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    定义xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="lesson1" class="com.example.lurenjia.spring.c22.jd4.LessonModel"/>
    
        <bean id="lesson2" parent="lesson1">
            <property name="name" value="spring高手系列"/>
            <property name="lessonCount" value="100"/>
        </bean>
    
        <bean id="lesson3" parent="lesson2">
            <property name="description" value="路人甲Java带你学spring,超越90%开发者!"/>
        </bean>
    </beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    public class Client {
        public static void main(String[] args) {
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(factory);
            beanDefinitionReader.loadBeanDefinitions("classpath:c22jd4d1.xml");
            for (String beanName : factory.getBeanDefinitionNames()) {
                BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
                BeanDefinition mergedBeanDefinition = factory.getMergedBeanDefinition(beanName);
                System.out.println(beanName);
                System.out.println("解析xml过程中注册的beanDefinition:" + beanDefinition);
                System.out.println("beanDefinition中的属性信息" + beanDefinition.getPropertyValues());
                System.out.println("合并之后得到的mergedBeanDefinition:" + mergedBeanDefinition);
                System.out.println("mergedBeanDefinition中的属性信息" + mergedBeanDefinition.getPropertyValues());
                System.out.println("---------------------------");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    lesson3
    解析xml过程中注册的beanDefinition:Generic bean with parent 'lesson2': 
    class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; 
    autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null;
     initMethodName=null; destroyMethodName=null; defined in class path resource [c22jd4d1.xml]
    beanDefinition中的属性信息PropertyValues: length=1; bean property 'description'
    合并之后得到的mergedBeanDefinition:Root bean: class [com.example.lurenjia.spring.c22.jd4.LessonModel]; 
    scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; 
    primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; 
    defined in class path resource [c22jd4d1.xml]
    mergedBeanDefinition中的属性信息PropertyValues: length=3; bean property 'name'; bean property 'lessonCount';
    bean property 'description'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    阶段5:Bean Class加载阶段 (resolveBeanClass)

    Resolve the bean class for the specified bean definition, resolving a bean class name into a Class reference (if necessary) and storing the resolved Class in the bean definition for further use.

    将 bean definition 解析为 bean class.

    	@Nullable
    	protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
    			throws CannotLoadBeanClassException {
    
    		try {
    			if (mbd.hasBeanClass()) {
    				return mbd.getBeanClass();
    			}
    			if (System.getSecurityManager() != null) {
    				return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
    						() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
    			}
    			else {
    				return doResolveBeanClass(mbd, typesToMatch);
    			}
    		}
    		catch (PrivilegedActionException pae) {
    			ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
    			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
    		}
    		catch (ClassNotFoundException ex) {
    			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
    		}
    		catch (LinkageError err) {
    			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    阶段6:Bean实例化阶段

    createBean方法

    		try {
    			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    			if (bean != null) {
    				return bean;
    			}
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    resolveBeforeInstantiation

    	@Nullable
    	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    		Object bean = null;
    		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    			// Make sure bean class is actually resolved at this point.
    			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    				Class<?> targetType = determineTargetType(beanName, mbd);
    				if (targetType != null) {
    					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    					if (bean != null) {
    						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    					}
    				}
    			}
    			mbd.beforeInstantiationResolved = (bean != null);
    		}
    		return bean;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    	@Nullable
    	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
    			if (result != null) {
    				return result;
    			}
    		}
    		return null;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    阶段7:合并后的BeanDefinition处理

    doCreateBean类583行applyMergedBeanDefinitionPostProcessors

    		// Allow post-processors to modify the merged bean definition. 
    		synchronized (mbd.postProcessingLock) {
    			if (!mbd.postProcessed) {
    				try {
    					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    				}
    				catch (Throwable ex) {
    					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    							"Post-processing of merged bean definition failed", ex);
    				}
    				mbd.postProcessed = true;
    			}
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    applyMergedBeanDefinitionPostProcessors

    	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    		for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
    			processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    postProcessMergedBeanDefinition是MergedBeanDefinitionPostProcessor接口的方法

    	void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
    
    • 1

    主要实现类 todo

    阶段8:Bean属性设置阶段

    		// Initialize the bean instance. 初始化bean实例
    		Object exposedObject = bean;
    		try {
    			//填充bean,涉及阶段8
    			populateBean(beanName, mbd, instanceWrapper);
    			//初始化bean,涉及阶段9
    			exposedObject = initializeBean(beanName, exposedObject, mbd);
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    populateBean方法源码

    	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    		//如果BeanWrapper为空
    		if (bw == null) {
    			if (mbd.hasPropertyValues()) {
    				throw new BeanCreationException(
    						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
    			}
    			//当mbd.hasPropertyValues()返回false
    			else {
    				// Skip property population phase for null instance. 跳过这个阶段
    				return;
    			}
    		}
    		
    		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    		// state of the bean before properties are set. This can be used, for example,
    		// to support styles of field injection.
    		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    				//如果postProcessAfterInstantiation返回false则跳过该阶段
    				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    					return;
    				}
    			}
    		}
    		//PropertyValues 
    		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    
    		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    			// Add property values based on autowire by name if applicable.
    			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    				autowireByName(beanName, mbd, bw, newPvs);
    			}
    			// Add property values based on autowire by type if applicable.
    			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    				autowireByType(beanName, mbd, bw, newPvs);
    			}
    			pvs = newPvs;
    		}
    
    		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    
    		PropertyDescriptor[] filteredPds = null;
    		if (hasInstAwareBpps) {
    			if (pvs == null) {
    				pvs = mbd.getPropertyValues();
    			}
    			//阶段2
    			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
    				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    				if (pvsToUse == null) {
    					if (filteredPds == null) {
    						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    					}
    					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    					if (pvsToUse == null) {
    						return;
    					}
    				}
    				pvs = pvsToUse;
    			}
    		}
    		if (needsDepCheck) {
    			if (filteredPds == null) {
    				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    			}
    			checkDependencies(beanName, mbd, filteredPds, pvs);
    		}
    
    		if (pvs != null) {
    			applyPropertyValues(beanName, mbd, bw, pvs);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    阶段9:Bean初始化阶段(初始化)

    包含阶段

    这个阶段含有几个小阶段

    • Bean Aware接口回调

    • Bean初始化前

    • Bean初始化

    • Bean初始化后

    主要原理 initializeBean 方法执行过程

    AbstractAutowireCapableBeanFactory类609行

    		exposedObject = initializeBean(beanName, exposedObject, mbd);
    
    • 1

    AbstractAutowireCapableBeanFactory类initializeBean方法源码如下

    	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    		//阶段1 处理aware方法
    		if (System.getSecurityManager() != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareMethods(beanName, bean);
    				return null;
    			}, getAccessControlContext());
    		}
    		else {
    			invokeAwareMethods(beanName, bean);
    		}
    		//阶段2 applyBeanPostProcessorsBeforeInitialization
    		Object wrappedBean = bean;
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    		}
    		//invokeInitMethods
    		try {
    			invokeInitMethods(beanName, wrappedBean, mbd);
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(
    					(mbd != null ? mbd.getResourceDescription() : null),
    					beanName, "Invocation of init method failed", ex);
    		}
    		//applyBeanPostProcessorsAfterInitialization
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    		}
    
    		return wrappedBean;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    Bean Aware接口回调

    https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-aware

    Aware原理

    initializeBean中关于invokeAwareMethods的调用

    		//阶段1 处理aware方法
    		if (System.getSecurityManager() != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareMethods(beanName, bean);
    				return null;
    			}, getAccessControlContext());
    		}
    		else {
    			invokeAwareMethods(beanName, bean);
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    aware翻译为:知道的;察觉的;了解的;关注的

    public interface Aware {}
    
    • 1

    虽然Aware接口什么方法都没有,但是它有非常多的实现类,org.springframework.beans.factory这个包下以Aware结尾的接口。核心代码 AbstractAutowireCapableBeanFactory 类

    	private void invokeAwareMethods(String beanName, Object bean) {
    		//Aware
    		if (bean instanceof Aware) {
    		    //BeanNameAware
    			if (bean instanceof BeanNameAware) {
    				((BeanNameAware) bean).setBeanName(beanName);
    			}
    			//BeanClassLoaderAware
    			if (bean instanceof BeanClassLoaderAware) {
    				ClassLoader bcl = getBeanClassLoader();
    				if (bcl != null) {
    					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
    				}
    			}
    			//BeanFactoryAware
    			if (bean instanceof BeanFactoryAware) {
    				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Aware案例

    public class AwareBean implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
    
        @Override
        public void setBeanName(String name) {
            System.out.println("setBeanName:" + name);
        }
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            System.out.println("setBeanFactory:" + beanFactory);
        }
    
        @Override
        public void setBeanClassLoader(ClassLoader classLoader) {
            System.out.println("setBeanClassLoader:" + classLoader);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    client

    public class Client {
        public static void main(String[] args) {
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            factory.registerBeanDefinition("awareBean",
                    BeanDefinitionBuilder.genericBeanDefinition(AwareBean.class).getBeanDefinition());
            factory.getBean("awareBean");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出

    setBeanName:awareBean
    setBeanClassLoader:sun.misc.Launcher$AppClassLoader@18b4aac2
    setBeanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@30c7da1e: defining beans [awareBean]; root of factory hierarchy
    
    • 1
    • 2
    • 3

    Bean初始化 (postProcessBeforeInitialization)

    原理

    initializeBean中关于applyBeanPostProcessorsBeforeInitialization的调用

    		Object wrappedBean = bean;
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    		}
    
    • 1
    • 2
    • 3
    • 4

    applyBeanPostProcessorsBeforeInitialization源码

    	@Override
    	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    			throws BeansException {
    
    		Object result = existingBean;
    		for (BeanPostProcessor processor : getBeanPostProcessors()) {
    			//方法的核心
    			Object current = processor.postProcessBeforeInitialization(result, beanName);
    			if (current == null) {
    				return result;
    			}
    			result = current;
    		}
    		return result;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    根据源码processor.postProcessBeforeInitialization这一行就是这个方法的核心。

    BeanPostProcessor接口中的postProcessBeforeInitialization默认实现

    	@Nullable
    	default Object postProcessBeforeInitialization(Object bean, String beanName) 
    	throws BeansException {
    		return bean;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    post 和 Process 通常翻译为:后处理,后续处理
    Before 在。。之前
    Initialization 初始化
    所以这个方法的意思为在初始化之前进行的处理过程。

    这个接口有2个实现类,比较重要:
    ApplicationContextAwareProcessor 和 CommonAnnotationBeanPostProcessor

    	@Override
    	@Nullable
    	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
    				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
    				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
    				bean instanceof ApplicationStartupAware)) {
    			return bean;
    		}
    
    		AccessControlContext acc = null;
    
    		if (System.getSecurityManager() != null) {
    			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    		}
    
    		if (acc != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareInterfaces(bean);
    				return null;
    			}, acc);
    		}
    		else {
    			invokeAwareInterfaces(bean);
    		}
    
    		return bean;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    案例

    Bean初始化(invokeInitMethods)

    源码来自initializeBean第三部分,翻译为调用初始化方法

    		//invokeInitMethods
    		try {
    			invokeInitMethods(beanName, wrappedBean, mbd);
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(
    					(mbd != null ? mbd.getResourceDescription() : null),
    					beanName, "Invocation of init method failed", ex);
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Give a bean a chance to react now all its properties are set, and a chance to know about its owning bean factory (this object). This means checking whether the bean implements InitializingBean or defines a custom init method, and invoking the necessary callback(s) if it does.

    invokeInitMethods源码,翻译为调用初始化方法。

    	protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
    			throws Throwable {
    		//bean是否实现InitializingBean接口
    		boolean isInitializingBean = (bean instanceof InitializingBean);
    		
    		if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
    			//如果是trace级别
    			if (logger.isTraceEnabled()) {
    				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    			}
    			//
    			if (System.getSecurityManager() != null) {
    				try {
    					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
    						((InitializingBean) bean).afterPropertiesSet();
    						return null;
    					}, getAccessControlContext());
    				}
    				catch (PrivilegedActionException pae) {
    					throw pae.getException();
    				}
    			}
    			else {
    				//调用afterPropertiesSet
    				((InitializingBean) bean).afterPropertiesSet();
    			}
    		}
    
    		if (mbd != null && bean.getClass() != NullBean.class) {
    			String initMethodName = mbd.getInitMethodName();
    			if (StringUtils.hasLength(initMethodName) &&
    					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    					!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
    				//调用	invokeCustomInitMethod
    				invokeCustomInitMethod(beanName, bean, mbd);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    主要作用就是调用 afterPropertiesSet和invokeCustomInitMethod

    afterPropertiesSet

    public interface InitializingBean {
    	//在配置文件设置之后
    	void afterPropertiesSet() throws Exception;
    }
    
    • 1
    • 2
    • 3
    • 4

    invokeCustomInitMethod

    	protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
    			throws Throwable {
    
    		String initMethodName = mbd.getInitMethodName();
    		Assert.state(initMethodName != null, "No init method set");
    		Method initMethod = (mbd.isNonPublicAccessAllowed() ?
    				BeanUtils.findMethod(bean.getClass(), initMethodName) :
    				ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
    
    		if (initMethod == null) {
    			if (mbd.isEnforceInitMethod()) {
    				throw new BeanDefinitionValidationException("Could not find an init method named '" +
    						initMethodName + "' on bean with name '" + beanName + "'");
    			}
    			else {
    				if (logger.isTraceEnabled()) {
    					logger.trace("No default init method named '" + initMethodName +
    							"' found on bean with name '" + beanName + "'");
    				}
    				// Ignore non-existent default lifecycle methods.
    				return;
    			}
    		}
    
    		if (logger.isTraceEnabled()) {
    			logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
    		}
    		Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod, bean.getClass());
    
    		if (System.getSecurityManager() != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				ReflectionUtils.makeAccessible(methodToInvoke);
    				return null;
    			});
    			try {
    				AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
    						() -> methodToInvoke.invoke(bean), getAccessControlContext());
    			}
    			catch (PrivilegedActionException pae) {
    				InvocationTargetException ex = (InvocationTargetException) pae.getException();
    				throw ex.getTargetException();
    			}
    		}
    		else {
    			try {
    				ReflectionUtils.makeAccessible(methodToInvoke);
    				methodToInvoke.invoke(bean);
    			}
    			catch (InvocationTargetException ex) {
    				throw ex.getTargetException();
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    Bean初始化后(postProcessAfterInitialization)

    源码来自initializeBean第四部分

    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    		}
    
    • 1
    • 2
    • 3

    applyBeanPostProcessorsAfterInitialization方法分析

    	@Override
    	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    			throws BeansException {
    		//当前bean	
    		Object result = existingBean;
    		//循环使用BeanPostProcessor 来处理
    		for (BeanPostProcessor processor : getBeanPostProcessors()) {
    			//使用每个处理器的postProcessAfterInitialization方法处理
    			Object current = processor.postProcessAfterInitialization(result, beanName);	
    			//如果处理后为null直接返回
    			if (current == null) {
    				return result;
    			}
    			result = current;
    		}
    		//所有的处理器处理完之后返回对象
    		return result;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    BeanPostProcessor接口postProcessAfterInitialization方法的默认实现

    	@Nullable
    	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    
    • 1
    • 2
    • 3
    • 4

    阶段9总结

    Bean初始化分为四个阶段,其中在初始化的前后分别有前后处理器处理。最前面是Aware接口的一些处理。

    We recommend that you do not use the InitializingBean interface, because it unnecessarily couples the code to Spring. Alternatively, we suggest using the @PostConstruct annotation or specifying a POJO initialization method.

    我们不推荐使用InitializingBean,这样会导致Spring耦合。推荐@PostConstruct。

    阶段10:所有单例bean初始化完成后阶段 (初始化后)

    SmartInitializingSingleton

    smart 轻量
    initializing 初始化
    singleton 单例

    Callback interface triggered at the end of the singleton pre-instantiation phase during BeanFactory bootstrap.

    at the end of the singleton pre-instantiation phase 在单例预实例化阶段之后,下面我们来一个案例

    public class Entity implements SmartInitializingSingleton {
    
        private static final Logger logger = LoggerFactory.getLogger(Entity.class);
    
        public Entity() {
            logger.info("entity is init ... ");
        }
    
        @Override
        public void afterSingletonsInstantiated() {
            logger.info("afterSingletonsInstantiated is callback");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出

    INFO com.example.lurenjia.spring.c22.jd11.Entity - entity is init ... 
    INFO com.example.lurenjia.spring.c22.jd11.Entity - afterSingletonsInstantiated is callback
    
    • 1
    • 2

    通过实现SmartInitializingSingleton 在初始化后执行

    DubboLoadBalancedRestTemplateAutoConfiguration 中的实践

    	@Override
    	public void afterSingletonsInstantiated() {
    		loadBalancerInterceptorBean = retryLoadBalancerInterceptor != null
    				? retryLoadBalancerInterceptor : loadBalancerInterceptor;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    阶段11:Bean使用阶段

    使用阶段相信大家都会不再赘述。

    阶段12:Bean销毁阶段

    案例1 DisposableBean

    public class Entity13 implements DisposableBean {
    
        private static final Logger logger = LoggerFactory.getLogger(Entity13.class);
    
        public Entity13() {
            logger.info("Entity13 is init ... ");
        }
    
        @Override
        public void destroy() throws Exception {
            logger.info("Entity13 is destroy ... ");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    @Configuration
    public class Config13 {
        @Bean
        Entity13 entity13() {
            return new Entity13();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class Client1 {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config13.class);
            Entity13 bean = context.getBean(Entity13.class);
            System.out.println(bean);
            context.getBeanFactory().destroyBean(bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出

    com.example.lurenjia.spring.c22.jd13.Entity13 - Entity13 is init ... 
    com.example.lurenjia.spring.c22.jd13.Entity13@318ba8c8
    com.example.lurenjia.spring.c22.jd13.Entity13 - Entity13 is destroy ... 
    
    • 1
    • 2
    • 3

    案例2 @PreDestroy

    public class Entity132 {
    
        private static final Logger logger = LoggerFactory.getLogger(Entity13.class);
    
        public Entity132() {
            logger.info("Entity132 is init ... ");
        }
    
        @PreDestroy
        public void destroy() {
            logger.info("Entity132 is destroy ... ");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出

     INFO com.example.lurenjia.spring.c22.jd13.Entity13 - Entity132 is destroy ... 
    
    • 1

    使用@PreDestroy标记销毁时调用的方法。

    案例3 DestructionAwareBeanPostProcessor

    public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
    
        private static final Logger logger = LoggerFactory.getLogger(MyDestructionAwareBeanPostProcessor.class);
    
        @Override
        public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
            logger.info(beanName + "is destroy");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    public class Client2 {
        public static void main(String[] args) {
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            //注册BeanPostProcessor
            factory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());
            //向容器中注入3个单例bean
            factory.registerBeanDefinition("entity2",
                    BeanDefinitionBuilder.genericBeanDefinition(Entity2.class)
                            .getBeanDefinition());
    
            factory.preInstantiateSingletons();
            factory.destroySingleton("entity2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出

    INFO com.example.lurenjia.spring.c22.jd13.d2.Entity2 - Entity2 init ... 
    INFO com.example.lurenjia.spring.c22.jd13.d2.MyDestructionAwareBeanPostProcessor - entity2is destroy
    
    • 1
    • 2

    总结

    • 实现DisposableBean
    • @PreDestroy标记销毁方法
    • 针对BeanDefinition实现DestructionAwareBeanPostProcessor

    We recommend that you do not use the DisposableBean callback interface, because it unnecessarily couples the code to Spring.

    Spring官方建议不要使用DisposableBean接口,因为会和Spring进行耦合。

    Alternatively, we suggest using the @PreDestroy annotation or specifying a generic method that is supported by bean definitions.

    我们建议使用@PreDestroy或者指定bean定义支持的通用方法。

    重要的类和接口

    AbstractApplicationContext

    public abstract class AbstractApplicationContext extends DefaultResourceLoader
    		implements ConfigurableApplicationContext {}
    
    • 1
    • 2

    BeanDefinitionRegistry

    AutowiredAnnotationBeanPostProcessor

    CommonAnnotationBeanPostProcessor

    BeanDefinition

    在这里插入图片描述
    在这里插入图片描述

    综合案例

    Container Extension Points 容器扩展点

    https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-extension

  • 相关阅读:
    ubuntu kill命令使用方法极简
    京东云开发者|IoT运维 - 如何部署一套高可用K8S集群
    leetcode 128. Longest Consecutive Sequence 最长连续序列(中等)
    sqlmap命令大全(附详细扫描流程)
    第九周内容回顾
    全球名校AI课程库(38)| 马萨诸塞大学 · 自然语言处理进阶课程『Advanced Natural Language Processing』
    2022年最新最全143道Java岗面试题及答案
    【嵌入式软件开发岗位 ---- 面试总结01】
    CSS中常用的伪类选择器
    Android广播BroadcastReceiver介绍
  • 原文地址:https://blog.csdn.net/qq_37151886/article/details/127558477