本文仅分析 obtainFreshBeanFactory() 这和prepareBeanFactory()方法,其他初始化参考系列文章~~
这里就是返回 BeanFactory 就不细说了
通过方法名判断,准备 BeanFactory,简单来说就是 做一些初始化 BeanFactory 的操作
private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore"); protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 设置 DefaultListableBeanFactory的 加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 通过在 spring.properties 配置是否开启 表达式语言解析器,默认是(不忽略) if (!shouldIgnoreSpel) { beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); } //设置属性编辑 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 添加一个 PostProcessor 也就是 ApplicationContextAwareProcessor, beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 忽略自动装配的接口, // Spring 会通过其他方式来处理这些依赖。 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. //注册可以解析的自动装配 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // 注册早期的后处理器以将内部bean检测为ApplicationListeners。 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 如果 beanFactory 已经存在则不会进行 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { // 注入环境属性, beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } // 如果 beanFactory 已经存在则不会进行 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { // 注入 系统的属性 beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } // 如果 beanFactory 已经存在则不会进行注册 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { // 注入 系统环境属性 beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }注册单例Bean
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { // 注册单例的Bean,此处注册的Bean 是没有spring 生命周期的,仅仅是将 beanName 和bean 做一个映射放入到缓存中 super.registerSingleton(beanName, singletonObject); // updateManualSingletonNames( set -> set.add(beanName), // 将name 添加到 set集合中 // beanDefinitionMap 判断这 个beanName // 不存在则 是true // 存在则为 false.. set -> !this.beanDefinitionMap.containsKey(beanName) ); // 清除缓存 clearByTypeCache(); }这里暂时不用管,是因为我们这些方法里面还没涉及到…
private void clearByTypeCache() { this.allBeanNamesByType.clear(); this.singletonBeanNamesByType.clear(); }在 resources 下面定义一个spring.proerties
spring.spel.ignore=true 可以进行输出一下,其原理大家可以看看这边就不贴了 private static void properties() { System.out.println(SpringProperties.getFlag("spring.spel.ignore")); }注册单例Bean,需要注意的是,此时注册的Bean 是没有 spring生命周期的,为啥这么说呢,是因为只要是 手动注册 都是对象是直接创建好的。是直接放到了 spring 一级缓存中
private static void prepareBeanFactory() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(PrepareRefreshContext.class); DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory(); // 注册 单体对象 beanFactory.registerSingleton("user",new User()); // 从容器中获取,这里我不会去将 getBean.. 阶段的代码. 因为太复杂了.. 但是我可以明确的告诉 // doGetBean(beanName)方法体中第二行代码就是--> getSingleton(beanName) 这样就直接去 取到了,所以不会有 spring的 各种回调~~~ User bean = beanFactory.getBean(User.class); System.out.println(bean); }而且只能注册一次,注册第二次则会失败…也就说相同的注册会失败…
private static void prepareBeanFactory() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(PrepareRefreshContext.class); DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory(); // 注册 单体对象 beanFactory.registerSingleton("user",new User()); // 二次注册一定出错 beanFactory.registerSingleton("user",new User()); }如果 registerSingleton 和 beanDefinitionMap 如果 beanDefinitionMap 有了也不会进行注册…
private static void prepareBeanFactory() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(PrepareRefreshContext.class); DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory(); beanFactory.registerBeanDefinition("user", BeanDefinitionBuilder.genericBeanDefinition(User.class).getBeanDefinition()); // 这里注册单体Bean 并不会注册到容器中,因为在注册前会先 去校验 BeanDefinitionMap 中做一个校验 beanFactory.registerSingleton("user",new User()); User bean = beanFactory.getBean(User.class); System.out.println(bean); }用相应的自动装配值注册一个特殊的依赖类型。且只能注册一次,为什么要这么做呢?在Spring自动装配的时候如果一个接口有多个实现类,并且都已经放到IOC中去了,那么自动装配的时候就会出异常,因为spring不知道把哪个实现类注入进去,这里不涉及@Primary的讲解,那有没有什么办法就是如果是这个类型的我就指定实现类来进行自动装配呢?registerResolvableDependency()这个方法的作用就是干这个的…
也就是说不能通过依赖查找,为什么?因为你注册的时候,spring 就压根没告诉你名字你怎么做依赖查找呀…
只能通过依赖注入的方式进行注入,简单来说只能通过类型进行注入…
@ComponentScan @Configuration public class ObtainFreshBeanFactoryContext { @Autowired private People people; public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(ObtainFreshBeanFactoryContext.class); registerResolvableDependency(context); context.refresh(); // 获取Bean ObtainFreshBeanFactoryContext bean = context.getBean(ObtainFreshBeanFactoryContext.class); // 获取我们使用 registerResolvableDependency 添加的Bean System.out.println(bean.people); } private static void registerResolvableDependency(AnnotationConfigApplicationContext context) { context.getBeanFactory().registerResolvableDependency(People.class, new ZhangSan()); } } interface People { }; class ZhangSan implements People { } class WangWu implements People { }