Spring实例化基本流程
Spring在容器初始化的时候,读取XMl配置,将其封装成BeanDefinition(Bean定义)对象,描述所有bean的信息
BeanDefinition会注册存储到beanDefinitionMap集合中
Spring框架遍历beanDefinitionMap,使用反射创建Bean实例对象
创建好之后的对象存储在singletonObjects的map集合中,当getBean时,从该map中取出实例bean对象返回

Spring配置文件中的配置项都能在BeanDefinition对象中找到

BeanDefinition是一个接口,我们使用RootBeanDefinition即可

Spring中的两个后处理器
Spring中提供两个后处理器,让我们能够介入实例化流程,动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用
BeanFactoryPostProcessor:Bean工厂后处理器,在beanDefinitionMap填充完毕,还未反射创建对象之前执行
BeanPostProcessor:Bean后处理器 ,在Bean实例化之后,填充至singletonObjects之前执行,一但添加至singletonObjects意味着不能改变
一个在还未创建对象之前,一个在创建对象之后
Bean工厂后处理器 BeanFactoryPostProcessor
BeanFactoryPostProcessor是一个接口,实现了该接口的类只要交由spring容器管理的话,那么spring就会回调该接口的方法,用于对BeanDefinition注册和修改
package com.tech.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("BeanDefinitionMap填充完毕之后执行该方法");
        // 创建一个BeanDefinition 
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClassName("com.tech.test.test.bean.DI");
        // 查看继承关系图ConfigurableListableBeanFactory就是DefaultListableBeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
        // 注册Bean
        defaultListableBeanFactory.registerBeanDefinition("userService",rootBeanDefinition);
        
    }
}
 
 <bean id="userService"  name="aaa,bbb"  class="com.tech.test.service.impl.UserServiceImpl" ></bean>
<bean  class="com.tech.test.processor.MyBeanFactoryProcessor "></bean> 
需要在配置文件中配置交给spring管理,这个示例 我们动态的修改对象userService为DI对象,当我们getBean时,Bean已经被修改为DI对象
spring提供了专门注册BeanDefinitionMap的接口,BeanDefinitionRegistryPostProcessor,看下继承关系,它是BeanFactoryPostProcessor 的子接口
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.beans.factory.support;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
 
演示相同功能
package com.tech.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class MyNoCastProcessor implements BeanDefinitionRegistryPostProcessor {
    // 执行顺序早于postProcessBeanFactory 简记为 谁在上边谁先执行
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        // 创建一个BeanDefinition
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClassName("com.tech.test.test.bean.DI");
        // 注册Bean
        beanDefinitionRegistry.registerBeanDefinition("userService",rootBeanDefinition);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    }
}
 
<bean id="userService"  name="aaa,bbb"  class="com.tech.test.service.impl.UserServiceImpl" ></bean>
<bean id="process" class="com.tech.test.processor.MyNoCastProcessor"></bean> 
示例:定义自定义注解实现注册对象,配置就不列举啦,需要在对象未创建之前加入Bean定义信息
自定义注解
package com.tech.test.anotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyComponent {
    String value();
}
 
加上注解
package com.tech.test.testbean;
import com.tech.test.anotation.MyComponent;
@MyComponent("ceshi")
public class TestAnnotation {
}
 
解析注解
package com.tech.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class ParseMyComponentProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        // 这里的全限定类名和注解中的名称应该扫描包得到,这里暂时写死
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClassName("com.tech.test.testbean.TestAnnotation");
        beanDefinitionRegistry.registerBeanDefinition("ceshi",rootBeanDefinition);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    }
}
 
测试注解
package com.tech.test.springtest;
import com.tech.test.testbean.DI;
import com.tech.test.testbean.TestAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestParseAnnotation {
    public static void main(String[] args) {
        // 创建ApplicationContext,加载配置文件,实例化容器
        ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取Bean
        TestAnnotation testAnnotation = classPathXmlApplicationContext.getBean(TestAnnotation.class);
        System.out.println(testAnnotation);
    }
}
 

Bean后处理器BeanPostProcessor
Bean后处理器 ,在Bean实例化之后,填充至singletonObjects之前执行,一但添加至singletonObjects意味着不能改变
示例:为spring中的Bean执行方法添加时间,执行开始之前加入时间,执行之后加入时间,这里使用jdk动态代理做增强
package com.tech.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import java.lang.reflect.Proxy;
import java.util.Date;
public class MyBeanProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Object proxyBean = Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("方法" + method.getName() + "开始时间" + new Date());
                    // 执行目标方法
                    Object invoke = method.invoke(bean, args);
                    System.out.println("方法" + method.getName() + "结束时间" + new Date());
                    return invoke;
        });
        return proxyBean;
    }
}
 
<bean  class="com.tech.test.processor.MyBeanProcessor"></bean> 
测试结果
package com.tech.test.springtest;
import com.tech.test.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApplicationContext {
    public static void main(String[] args) {
        ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService =(UserService) classPathXmlApplicationContext.getBean("userService");
        userService.getUser();
    }
}
 



















