SpringBoot自动配置的实现原理
参考资料
什么是BeanDefinition
BeanDefinition源码解析
BeanDefinition基础信
BeanDefinition
Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构
参考资料的解析代码
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { // 我们可以看到,默认只提供 sington 和 prototype 两种, // 很多读者可能知道还有 request, session, globalSession, application, websocket 这几种, // 不过,它们属于基于 web 的扩展。 String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; // 比较不重要,直接跳过吧 int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; // 设置父 Bean,这里涉及到 bean 继承,不是 java 继承。请参见附录的详细介绍 // 一句话就是:继承父 Bean 的配置信息而已 void setParentName(String parentName); // 获取父 Bean String getParentName(); // 设置 Bean 的类名称,将来是要通过反射来生成实例的 void setBeanClassName(String beanClassName); // 获取 Bean 的类名称 String getBeanClassName(); // 设置 bean 的 scope void setScope(String scope); String getScope(); // 设置是否懒加载 void setLazyInit(boolean lazyInit); boolean isLazyInit(); // 设置该 Bean 依赖的所有的 Bean,注意,这里的依赖不是指属性依赖(如 @Autowire 标记的), // 是 depends-on="" 属性设置的值。 void setDependsOn(String... dependsOn); // 返回该 Bean 的所有依赖 String[] getDependsOn(); // 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效, // 如果根据名称注入,即使这边设置了 false,也是可以的 void setAutowireCandidate(boolean autowireCandidate); // 该 Bean 是否可以注入到其他 Bean 中 boolean isAutowireCandidate(); // 主要的。同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean void setPrimary(boolean primary); // 是否是 primary 的 boolean isPrimary(); // 如果该 Bean 采用工厂方法生成,指定工厂名称。对工厂不熟悉的读者,请参加附录 // 一句话就是:有些实例不是用反射生成的,而是用工厂模式生成的 void setFactoryBeanName(String factoryBeanName); // 获取工厂名称 String getFactoryBeanName(); // 指定工厂类中的 工厂方法名称 void setFactoryMethodName(String factoryMethodName); // 获取工厂类中的 工厂方法名称 String getFactoryMethodName(); // 构造器参数 ConstructorArgumentValues getConstructorArgumentValues(); // Bean 中的属性值,后面给 bean 注入属性值的时候会说到 MutablePropertyValues getPropertyValues(); // 是否 singleton boolean isSingleton(); // 是否 prototype boolean isPrototype(); // 如果这个 Bean 是被设置为 abstract,那么不能实例化, // 常用于作为 父bean 用于继承,其实也很少用...... boolean isAbstract(); int getRole(); String getDescription(); String getResourceDescription(); } public class BeanDefinitionHolder implements BeanMetadataElement { private final BeanDefinition beanDefinition; private final String beanName;//beanID @Nullable private final String[] aliases;//Bean的别名数组 } public interface AttributeAccessor { //设置类属性 void setAttribute(String var1, @Nullable Object var2); @Nullable Object getAttribute(String var1); @Nullable Object removeAttribute(String var1); //是否拥有类属性 boolean hasAttribute(String var1); //获取所有类属性名 String[] attributeNames(); }
Spring 提供 一个扩展机会,在Bean还没实例化可以修改我们的bean定义的属性 BeanFactoryPostProcessor 可以修改实例化类 修改是否懒加载
@SpringBootApplication public class SpringbootdemoApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringbootdemoApplication.class, args); System.out.println(applicationContext.getBean("person")); } @Bean public Person person() { return new Person(); } } class Person { public Person() { System.out.println("Person"); } } @Component class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition("person"); beanDefinition.setLazyInit(true); } }
相关类
EnableAutoConfiguration -> @Import(AutoConfigurationImportSelector.class)