赞
踩
Spring源码分析-启动流程浅析
Spring源码分析-Spring源码分析-BeanDefinition
Spring源码分析-Bean生命周期概述
Spring源码分析-Bean生命周期查找与注册
Spring源码分析-Bean生命周期查找与注册(2)
BeanDefinition相当于Bean meta信息,后续创建Bean对象都需要依据BeanDefinition,因此这里需要介绍一下
BeanDefinition是一个接口,接口定义如下:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { /** * 单例bean */ String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; /** * 原型bean */ String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; /** * bean的Role属性 现在基本废弃 */ int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; // Modifiable attributes // 设置父BeanDefinition名称 void setParentName(@Nullable String parentName); @Nullable String getParentName(); /** * bean全类名称 */ void setBeanClassName(@Nullable String beanClassName); @Nullable String getBeanClassName(); /** * 设置bean的作用域 单例 或者 原型 */ void setScope(@Nullable String scope); @Nullable String getScope(); /** * 懒加载模式 */ void setLazyInit(boolean lazyInit); boolean isLazyInit(); /** * Set the names of the beans that this bean depends on being initialized. * The bean factory will guarantee that these beans get initialized first. */ void setDependsOn(@Nullable String... dependsOn); @Nullable String[] getDependsOn(); /** * Set whether this bean is a candidate for getting autowired into some other bean. * <p>Note that this flag is designed to only affect type-based autowiring. * It does not affect explicit references by name, which will get resolved even * if the specified bean is not marked as an autowire candidate. As a consequence, * autowiring by name will nevertheless inject a bean if the name matches. */ void setAutowireCandidate(boolean autowireCandidate); /** * Return whether this bean is a candidate for getting autowired into some other bean. */ boolean isAutowireCandidate(); /** * 设置当前bean为主要的, @Primary */ void setPrimary(boolean primary); boolean isPrimary(); /** * Specify the factory bean to use, if any. * This the name of the bean to call the specified factory method on. * @see #setFactoryMethodName */ void setFactoryBeanName(@Nullable String factoryBeanName); @Nullable String getFactoryBeanName(); /** * Specify a factory method, if any. This method will be invoked with * constructor arguments, or with no arguments if none are specified. * The method will be invoked on the specified factory bean, if any, * or otherwise as a static method on the local bean class. * @see #setFactoryBeanName * @see #setBeanClassName */ void setFactoryMethodName(@Nullable String factoryMethodName); /** * Return a factory method, if any. */ @Nullable String getFactoryMethodName(); /** * Return the constructor argument values for this bean. * <p>The returned instance can be modified during bean factory post-processing. * @return the ConstructorArgumentValues object (never {@code null}) */ ConstructorArgumentValues getConstructorArgumentValues(); /** * Return if there are constructor argument values defined for this bean. * @since 5.0.2 */ default boolean hasConstructorArgumentValues() { return !getConstructorArgumentValues().isEmpty(); } /** * Return the property values to be applied to a new instance of the bean. * <p>The returned instance can be modified during bean factory post-processing. * @return the MutablePropertyValues object (never {@code null}) */ MutablePropertyValues getPropertyValues(); /** * Return if there are property values defined for this bean. * @since 5.0.2 */ default boolean hasPropertyValues() { return !getPropertyValues().isEmpty(); } /** * Set the name of the initializer method. * @since 5.1 */ void setInitMethodName(@Nullable String initMethodName); /** * Return the name of the initializer method. * @since 5.1 */ @Nullable String getInitMethodName(); /** * Set the name of the destroy method. * @since 5.1 */ void setDestroyMethodName(@Nullable String destroyMethodName); /** * Return the name of the destroy method. * @since 5.1 */ @Nullable String getDestroyMethodName(); void setRole(int role); int getRole(); /** * Set a human-readable description of this bean definition. * @since 5.1 */ void setDescription(@Nullable String description); /** * Return a human-readable description of this bean definition. */ @Nullable String getDescription(); // Read-only attributes /** * Return a resolvable type for this bean definition, * based on the bean class or other specific metadata. * <p>This is typically fully resolved on a runtime-merged bean definition * but not necessarily on a configuration-time definition instance. * @return the resolvable type (potentially {@link ResolvableType#NONE}) * @since 5.2 * @see ConfigurableBeanFactory#getMergedBeanDefinition */ ResolvableType getResolvableType(); /** * 是否为单例 */ boolean isSingleton(); /** * 是否为原型 */ boolean isPrototype(); /** * Return whether this bean is "abstract", that is, not meant to be instantiated. */ boolean isAbstract(); /** * Return a description of the resource that this bean definition * came from (for the purpose of showing context in case of errors). */ @Nullable String getResourceDescription(); /** * Return the originating BeanDefinition, or {@code null} if none. * <p>Allows for retrieving the decorated bean definition, if any. * <p>Note that this method returns the immediate originator. Iterate through the * originator chain to find the original BeanDefinition as defined by the user. */ @Nullable BeanDefinition getOriginatingBeanDefinition(); }
BeanDefinition接口中注入比较详细,大家可以参考源码。主要包括如下属性:bean的作用域,bean是否为Primary,bean是否需要FactoryBean,Init/Destroy方法等。
spring代码优秀之处,基本上所有的接口,它都会提供一个实现类,而这个实现类往往都是抽象的(Abstract)。我们接下来看一下AbstractBeanDefinition做了哪些工作
@Nullable private volatile Object beanClass; //bean name @Nullable private String scope = SCOPE_DEFAULT; //作用域 SCOPE_SINGLETON private boolean abstractFlag = false; //是否为抽象 @Nullable private Boolean lazyInit; private int autowireMode = AUTOWIRE_NO; //自动注入 private int dependencyCheck = DEPENDENCY_CHECK_NONE; @Nullable private String[] dependsOn; private boolean autowireCandidate = true; //是否为主要的, 在按照类型给属性注入时,若出现冲突则查看是否存在@Primary注解 当存在这个注解则字段为true private boolean primary = false; @Nullable private String factoryBeanName; //工厂bean名字 @Nullable private String factoryMethodName; //工厂方法名字 @Nullable private ConstructorArgumentValues constructorArgumentValues; @Nullable private MutablePropertyValues propertyValues; private MethodOverrides methodOverrides = new MethodOverrides(); @Nullable private String initMethodName; @Nullable private String destroyMethodName;
看到这里不知道大家是否感觉到,这个数据结构很像spring.xml中配置项,不错,这个类(接口)就是spring.xml文件抽像模型。
/** * Specify the class for this bean. * @see #setBeanClassName(String) */ public void setBeanClass(@Nullable Class<?> beanClass) { this.beanClass = beanClass; } /** * Specify the bean class name of this bean definition. */ @Override public void setBeanClassName(@Nullable String beanClassName) { this.beanClass = beanClassName; } public String getBeanClassName() { Object beanClassObject = this.beanClass; if (beanClassObject instanceof Class) { return ((Class<?>) beanClassObject).getName(); } else { return (String) beanClassObject; } } public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException { String className = getBeanClassName(); if (className == null) { return null; } Class<?> resolvedClass = ClassUtils.forName(className, classLoader); this.beanClass = resolvedClass; return resolvedClass; }
AbstractBeanDefinition并没有提供注册的功能,所以注册是在外部实现的,这也体现了一种设计模式:单一职责模式。
在上一篇介绍Spring源码分析-启动流程浅析中有提到会进行包扫描,这个扫描过程其实就是注册BeanDefinition。
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>(); for (String basePackage : basePackages) { //扫描组件 返回的类型是BeanDefinition,实际是ScannedGenericBeanDefinition Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } if (checkCandidate(beanName, candidate)) {//判断registry中是否存在BeanDefinition 如果没有则创建 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); registerBeanDefinition(definitionHolder, this.registry);//注册BeanDefinition } } } return beanDefinitions; }
在注解场景下,入口类AnnotationConfigApplicationContext继承GenericApplicationContext,在GenericApplicationContext中有一个属性用于保存BeanDefinition
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
//DefaultListableBeanFactory, 默认Bean工厂,用于产生bean对象
private final DefaultListableBeanFactory beanFactory;
...
}
DefaultListableBeanFactory核心字段
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { /** Map from dependency type to corresponding autowired value. */ private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16); /** Map of bean definition objects, keyed by bean name. key=bean名字 value=BeanDefinition */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); /** Map from bean name to merged BeanDefinitionHolder. */ private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256); /** Map of singleton and non-singleton bean names, keyed by dependency type. */ private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64); /** Map of singleton-only bean names, keyed by dependency type. */ private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64); /** List of bean definition names, in registration order. 保存bean definition name */ private volatile List<String> beanDefinitionNames = new ArrayList<>(256); /** List of names of manually registered singletons, in registration order. */ private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16); ... }
通过上面的源码可知,这些map,list就是用于存与BeanDefinition相关的内容,下面是注册BeanDefinition核心方法
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) {//表示已经存在BeanDefinition if (!isAllowBeanDefinitionOverriding()) {//是否允许覆盖已经存在BeanDefinition throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition);//覆盖 } else {//BeanDefinition不存在 if (hasBeanCreationStarted()) {// 非启动流程注册beanDefinition, 例如动态注册 // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition);//放到map中 List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else {//启动注册阶段 // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition);//放到map中 this.beanDefinitionNames.add(beanName); //保存注册的beanName removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } else if (isConfigurationFrozen()) { clearByTypeCache(); } }
public class UserService { private Map<String, User> map = new ConcurrentHashMap<>(); public UserService() { System.out.println("UserService init...."); } public User getUser(String name) { return map.get(name); } public void addUser(User user) { map.put(user.getUsername(), user); } } public class WApp { public static void main(String[] args) { GenericApplicationContext context = new AnnotationConfigApplicationContext("com.worker"); GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(UserService.class); context.registerBeanDefinition("userService", beanDefinition); //动态注册BeanDefinition //获取bean时,如果bean不存在则去查找是否存在BeanDefinition,如果存在则根据BeanDefinition实例化Bean System.out.println(context.getBean("userService")); } }
总体来说,BeanDefinition相关的内容不是很复杂,只要知道BeanDefinition的作用以及包扫描的作用即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。