BeanDefinition 在spring
容器中通过BeanDefinition将在xml、注解等地方的bean定义解析并存储在BeanDefinition中。我们可以通过定义一个BeanDefinition
对象来表示定义了一个Bean,然后通过容器进行获取。
首先创建一个实体类:user
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 public class User { private Integer id; private String name; public void init () { System.out.println("init方法" ); } public Integer getId () { return id; } public void setId (Integer id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name; } @Override public String toString () { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}' ; } }
测试类:
1 2 3 4 5 6 7 8 9 10 11 12 @Test public void simple () { DefaultListableBeanFactory defaultListableBeanFactory=new DefaultListableBeanFactory (); AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition(); beanDefinition.setBeanClass(User.class); beanDefinition.setLazyInit(false ); beanDefinition.setScope("prototype" ); beanDefinition.setInitMethodName("init" ); defaultListableBeanFactory.registerBeanDefinition("user" ,beanDefinition); System.out.println(defaultListableBeanFactory.getBean("user" )); }
通过,@Bean
,@Component
等方式所定义的Bean,最终都会被解析为BeanDefinition
对象。要理解 BeanDefinition
,可以从 BeanDefinition
的继承关系开始看起:
可以看到 BeanDefinition
是一个接口,继承自 BeanMetadataElement
和 AttributeAccessor
接口。
AttributeAccessor
:定义用于附加和访问元数据的通用协定的接口,可以是任意对象。具体的实现则是 AttributeAccessorSupport
,采用 LinkedHashMap
进行存储。
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 public interface AttributeAccessor { void setAttribute (String name, @Nullable Object value) ; @Nullable Object getAttribute (String name) ; @SuppressWarnings("unchecked") default <T> T computeAttribute (String name, Function<String, T> computeFunction) { Assert.notNull(name, "Name must not be null" ); Assert.notNull(computeFunction, "Compute function must not be null" ); Object value = getAttribute(name); if (value == null ) { value = computeFunction.apply(name); Assert.state(value != null , () -> String.format("Compute function must not return null for attribute named '%s'" , name)); setAttribute(name, value); } return (T) value; } @Nullable Object removeAttribute (String name) ; boolean hasAttribute (String name) ; String[] attributeNames(); }
BeanMetadataElement
:该接口只有一个方法 getSource,该方法返回 Bean 的来源。
这是 BeanDefinition
所继承的两个接口。接下来来看下 BeanDefinition
本身。
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 public interface BeanDefinition extends AttributeAccessor , BeanMetadataElement { String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; int ROLE_APPLICATION = 0 ; int ROLE_SUPPORT = 1 ; int ROLE_INFRASTRUCTURE = 2 ; void setParentName (@Nullable String parentName) ; @Nullable String getParentName () ; void setBeanClassName (@Nullable String beanClassName) ; @Nullable String getBeanClassName () ; void setScope (@Nullable String scope) ; @Nullable String getScope () ; void setLazyInit (boolean lazyInit) ; boolean isLazyInit () ; void setDependsOn (@Nullable String... dependsOn) ; @Nullable String[] getDependsOn(); void setAutowireCandidate (boolean autowireCandidate) ; boolean isAutowireCandidate () ; void setPrimary (boolean primary) ; boolean isPrimary () ; void setFactoryBeanName (@Nullable String factoryBeanName) ; @Nullable String getFactoryBeanName () ; void setFactoryMethodName (@Nullable String factoryMethodName) ; @Nullable String getFactoryMethodName () ; ConstructorArgumentValues getConstructorArgumentValues () ; default boolean hasConstructorArgumentValues () { return !getConstructorArgumentValues().isEmpty(); } MutablePropertyValues getPropertyValues () ; default boolean hasPropertyValues () { return !getPropertyValues().isEmpty(); } void setInitMethodName (@Nullable String initMethodName) ; @Nullable String getInitMethodName () ; void setDestroyMethodName (@Nullable String destroyMethodName) ; @Nullable String getDestroyMethodName () ; void setRole (int role) ; int getRole () ; void setDescription (@Nullable String description) ; @Nullable String getDescription () ; ResolvableType getResolvableType () ; boolean isSingleton () ; boolean isPrototype () ; boolean isAbstract () ; @Nullable String getResourceDescription () ; @Nullable BeanDefinition getOriginatingBeanDefinition () ; }
BeanDefinition实现类 BeanDefinition
是一个接口,它有多个实现类,这些实现类分别描述不同类型的 Bean。大致分为两种:
继承关系如下:
删除掉了ClassDerivedBeanDefinition
这个内部类,形成上面类图
抽象实现:AbstractBeanDefinition AbstractBeanDefinition
是一个抽象类,BeanDefinition
中只是定义了一系列的 get/set 方法,并没有提供对应的属性,在 AbstractBeanDefinition
中将所有的属性定义出来了。该抽象类下有个三个子类:GenericBeanDefinition
、RootBeanDefinition
、ChildBeanDefinition
。我们先来看 AbstractBeanDefinition
本身的一些方法与属性。
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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 @SuppressWarnings("serial") public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition , Cloneable { public static final String SCOPE_DEFAULT = "" ; public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO; public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR; @Deprecated public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT; public static final int DEPENDENCY_CHECK_NONE = 0 ; public static final int DEPENDENCY_CHECK_OBJECTS = 1 ; public static final int DEPENDENCY_CHECK_SIMPLE = 2 ; public static final int DEPENDENCY_CHECK_ALL = 3 ; public static final String INFER_METHOD = "(inferred)" ; @Nullable private volatile Object beanClass; @Nullable private String scope = SCOPE_DEFAULT; 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 ; private boolean primary = false ; private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap <>(); @Nullable private Supplier<?> instanceSupplier; private boolean nonPublicAccessAllowed = true ; private boolean lenientConstructorResolution = true ; @Nullable private String factoryBeanName; @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; private boolean enforceInitMethod = true ; private boolean enforceDestroyMethod = true ; private boolean synthetic = false ; private int role = BeanDefinition.ROLE_APPLICATION; @Nullable private String description; @Nullable private Resource resource; }
RootBeanDefinition BeanDefinition
是可以分层级的,因为有ParentName
的getter/setter
。这个在进行 BeanDefinition
的配置时更加灵活,也可以进行配置的复用;但是在 Bean
实例构建时就很难受了,我构建一个 Bean
还有递归的去父类找配置。。。
所以我们想出了一个解决方法——在构建 Bean
实例时,先把 BeanDefinition
拍平 ,这样所有的配置就都在一个BeanDefinition
中了。这就是RootBeanDefinition
的主要使用场景,在这种场景下因为是拍平的,所以变量名一般叫 mergedBeanDefinition
或者mbd
。
注意: RootBeanDefinition
中在AbstractBeanDefinition
的基础上增加了很多的实例属性以方便使用。当然,两者各有侧重点:
AbstractBeanDefinition
:是对通用功能的扩展,是为了兼顾 BD
梳理和Bean实例化两个场景的。所以主要是一些属性的扩展和对属性的标记(标记捷径)
RootBeanDefinition
:主要在 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 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 77 78 79 80 81 82 83 84 85 86 public class RootBeanDefinition extends AbstractBeanDefinition { @Nullable private BeanDefinitionHolder decoratedDefinition; @Nullable private AnnotatedElement qualifiedElement; volatile boolean stale; boolean allowCaching = true ; boolean isFactoryMethodUnique; @Nullable volatile ResolvableType targetType; @Nullable volatile Class<?> resolvedTargetType; @Nullable volatile Boolean isFactoryBean; @Nullable volatile ResolvableType factoryMethodReturnType; @Nullable volatile Method factoryMethodToIntrospect; @Nullable volatile String resolvedDestroyMethodName; final Object constructorArgumentLock = new Object (); @Nullable Executable resolvedConstructorOrFactoryMethod; boolean constructorArgumentsResolved = false ; @Nullable Object[] resolvedConstructorArguments; @Nullable Object[] preparedConstructorArguments; final Object postProcessingLock = new Object (); boolean postProcessed = false ; @Nullable volatile Boolean beforeInstantiationResolved; @Nullable private Set<Member> externallyManagedConfigMembers; @Nullable private Set<String> externallyManagedInitMethods; @Nullable private Set<String> externallyManagedDestroyMethods; }
例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Test public void rootBeanDefinitionTest () { DefaultListableBeanFactory context = new DefaultListableBeanFactory (); MutablePropertyValues mpvs = new MutablePropertyValues (); mpvs.add("id" ,4 ); mpvs.add("name" ,"gongj" ); RootBeanDefinition rootBeanDefinition = new RootBeanDefinition (User.class,null ,mpvs); context.registerBeanDefinition("user" ,rootBeanDefinition); User user=(User)context.getBean("user" ); System.out.println(user); }
ChildBeanDefinition 该类继承自 AbstractBeanDefinition
。其相当于一个子类,不可以单独存在,必须依赖一个父 BeanDetintion
,构造 ChildBeanDefinition
时,通过构造方法传入父 BeanDetintion
的名称或通过 setParentName
设置父名称。它可以从父类继承方法参数、属性值,并可以重写父类的方法,同时也可以增加新的属性或者方法。
增加了 parentName
,指向父 BD 。已弃用,参考 GenericBeanDefinition
例子:
新建Person类,在User类的基础上增加一个address属性
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 public class Person { private Integer id; private String name; private String address; public void setId (Integer id) { this .id = id; } public Integer getId () { return id; } public String getName () { return name; } public void setName (String name) { this .name = name; } public String getAddress () { return address; } public void setAddress (String address) { this .address = address; } @Override public String toString () { return "Person{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", address='" + address + '\'' + '}' ; } }
测试方法:
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 @Test public void childDefinitionTest () { DefaultListableBeanFactory context = new DefaultListableBeanFactory (); MutablePropertyValues mpvs = new MutablePropertyValues (); mpvs.add("id" ,4 ); mpvs.add("name" ,"gongj" ); RootBeanDefinition rootBeanDefinition = new RootBeanDefinition (User.class,null ,mpvs); context.registerBeanDefinition("user" ,rootBeanDefinition); MutablePropertyValues childValues = new MutablePropertyValues (); childValues.add("address" ,"上海市" ); ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition ("user" , Person.class,null ,childValues); context.registerBeanDefinition("person" , childBeanDefinition); User user = context.getBean(User.class); Person person = context.getBean(Person.class); System.out.println("user = " + user); System.out.println("person = " + person); }
GenericBeanDefinition GenericBeanDefinition
是从 Spring2.5 以后新加入的 bean 文件配置属性定义类,是一站式服务类。GenericBeanDefinition
可以动态设置父 Bean,同时兼具 RootBeanDefinition
和 ChildBeanDefinition
的功能。
GenericBeanDefinition
的实现比较简单,在 AbstractBeanDefinition
的基础上只增加了parentName
的功能,其余的实现都在父类 AbstractBeanDefinition
里。
注:若你是xml配置,会解析所有属性并统一封装至 GenericBeanDefinition 类型的实例中,之后再逐渐解析的。
源码 1 2 3 4 5 6 public class GenericBeanDefinition extends AbstractBeanDefinition { @Nullable private String parentName; }
例子 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 @Test public void genericBeanDefinitionTest () { DefaultListableBeanFactory ctx = new DefaultListableBeanFactory (); MutablePropertyValues mpvs = new MutablePropertyValues (); mpvs.add("id" ,4 ); mpvs.add("name" ,"gongj" ); GenericBeanDefinition parentGenericBeanDefinition = new GenericBeanDefinition (); parentGenericBeanDefinition.setBeanClass(User.class); parentGenericBeanDefinition.setPropertyValues(mpvs); ctx.registerBeanDefinition("user" ,parentGenericBeanDefinition); GenericBeanDefinition childGenericBeanDefinition = new GenericBeanDefinition (); childGenericBeanDefinition.setParentName("user" ); childGenericBeanDefinition.setBeanClass(Person.class); childGenericBeanDefinition.getPropertyValues().add("address" , "上海市" ); ctx.registerBeanDefinition("person" , childGenericBeanDefinition); User user = ctx.getBean(User.class); Person person = ctx.getBean(Person.class); System.out.println("user = " + user); System.out.println("person = " + person); }
子接口:AnnotatedBeanDefinition 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public interface AnnotatedBeanDefinition extends BeanDefinition { AnnotationMetadata getMetadata () ; @Nullable MethodMetadata getFactoryMethodMetadata () ; }
该接口可以返回两个元数据的类:
AnnotationMetadata:主要对 Bean 的注解信息进行操作,如:获取当前 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 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 public interface AnnotationMetadata extends ClassMetadata , AnnotatedTypeMetadata { default Set<String> getAnnotationTypes () { return getAnnotations().stream() .filter(MergedAnnotation::isDirectlyPresent) .map(annotation -> annotation.getType().getName()) .collect(Collectors.toCollection(LinkedHashSet::new )); } default Set<String> getMetaAnnotationTypes (String annotationName) { MergedAnnotation<?> annotation = getAnnotations().get(annotationName, MergedAnnotation::isDirectlyPresent); if (!annotation.isPresent()) { return Collections.emptySet(); } return MergedAnnotations.from(annotation.getType(), SearchStrategy.INHERITED_ANNOTATIONS).stream() .map(mergedAnnotation -> mergedAnnotation.getType().getName()) .collect(Collectors.toCollection(LinkedHashSet::new )); } default boolean hasAnnotation (String annotationName) { return getAnnotations().isDirectlyPresent(annotationName); } default boolean hasMetaAnnotation (String metaAnnotationName) { return getAnnotations().get(metaAnnotationName, MergedAnnotation::isMetaPresent).isPresent(); } default boolean hasAnnotatedMethods (String annotationName) { return !getAnnotatedMethods(annotationName).isEmpty(); } Set<MethodMetadata> getAnnotatedMethods (String annotationName) ; static AnnotationMetadata introspect (Class<?> type) { return StandardAnnotationMetadata.from(type); } }
MethodMetadata:方法的元数据类。提供获取方法名称、此方法所属类的全类名、是否是抽象方法、判断是否是静态方法、判断是否是final方法等。
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 public interface MethodMetadata extends AnnotatedTypeMetadata { String getMethodName () ; String getDeclaringClassName () ; String getReturnTypeName () ; boolean isAbstract () ; boolean isStatic () ; boolean isFinal () ; boolean isOverridable () ; }
该接口下有三大子类: ScannedGenericBeanDefinition
、ConfigurationClassBeanDefinition
、AnnotatedGenericBeanDefinition
ScannedGenericBeanDefinition 实现了 AnnotatedBeanDefinition
也继承了 GenericBeanDefinition
。这个 BeanDefinition
用来描述标注@Component、@Service、@Controller
等注解标记的类会解析为 ScannedGenericBeanDefinition
。
它的源码很简单,就是多了一个属性:metadata
用来存储扫描进来的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 29 30 31 public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition { private final AnnotationMetadata metadata; public ScannedGenericBeanDefinition (MetadataReader metadataReader) { Assert.notNull(metadataReader, "MetadataReader must not be null" ); this .metadata = metadataReader.getAnnotationMetadata(); setBeanClassName(this .metadata.getClassName()); setResource(metadataReader.getResource()); } @Override public final AnnotationMetadata getMetadata () { return this .metadata; } @Override @Nullable public MethodMetadata getFactoryMethodMetadata () { return null ; } }
例子 新建AppConfig
类,用来扫描@Compent
等注解
1 2 3 @ComponentScan(basePackages ={"com.wch.study.spring"} ) public class AppConfig {}
新建IndexController
类,添加@Controller
注解
1 2 3 4 @Controller public class IndexController {}
测试:
1 2 3 4 5 6 @Test public void scannedGenericBeanDefinitionTest () { AnnotationConfigApplicationContext configApplicationContext=new AnnotationConfigApplicationContext (AppConfig.class); BeanDefinition indexController = configApplicationContext.getBeanFactory().getBeanDefinition("indexController" ); System.out.println(indexController.getClass()); }
ConfigurationClassBeanDefinition 该类继承自 GenericBeanDefinition
,并实现了AnnotatedBeanDefinition
接口。这个 BeanDefinition
用来描述标注使用了 @Configuration
注解标记配置类会解析为 AnnotatedGenericBeanDefinition
。
源码 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 @SuppressWarnings("serial") public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition { private final AnnotationMetadata metadata; @Nullable private MethodMetadata factoryMethodMetadata; public AnnotatedGenericBeanDefinition (Class<?> beanClass) { setBeanClass(beanClass); this .metadata = AnnotationMetadata.introspect(beanClass); } public AnnotatedGenericBeanDefinition (AnnotationMetadata metadata) { Assert.notNull(metadata, "AnnotationMetadata must not be null" ); if (metadata instanceof StandardAnnotationMetadata) { setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass()); } else { setBeanClassName(metadata.getClassName()); } this .metadata = metadata; } public AnnotatedGenericBeanDefinition (AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata) { this (metadata); Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null" ); setFactoryMethodName(factoryMethodMetadata.getMethodName()); this .factoryMethodMetadata = factoryMethodMetadata; } @Override public final AnnotationMetadata getMetadata () { return this .metadata; } @Override @Nullable public final MethodMetadata getFactoryMethodMetadata () { return this .factoryMethodMetadata; } }
例子 新建Myconfig类,增加@Configuration注解
1 2 3 4 5 @Configuration public class MyConfig {}
1 2 3 4 5 6 @Test public void annotatedGenericBeanDefinitionTest () { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (MyConfig.class); BeanDefinition myConfig = context.getBeanFactory().getBeanDefinition("myConfig" ); System.out.println(myConfig.getClass()); }
ConfigurationClassBeanDefinition 它是ConfigurationClassBeanDefinitionReader
的一个私有的静态内部类:这个类负责将@Bean
注解的方法转换为对应的ConfigurationClassBeanDefinition
类,源码就不过多解释了,和之前几个BeanDefinition
差不多。
其功能特点如下:
1、如果 @Bean
注解没有指定 Bean 的名字,默认会用方法的名字作为Bean的名称。
2、标注 @Configuration、@Component、@Service
注解的类会成为一个工厂类,而标注 @Bean
注解的方法会成为工厂方法,通过工厂方法实例化 Bean。
例子 在MyConfig类新增方法
1 2 3 4 @Bean("qq") public User myUserBean () { return new User (); }
测试
1 2 3 4 5 6 @Test public void configurationClassBeanDefinitionTest () { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (MyConfig.class); BeanDefinition qq = context.getBeanFactory().getBeanDefinition("qq" ); System.out.println(qq.getClass()); }
spring初始化时,会用GenericBeanDefinition或是ConfigurationClassBeanDefinition(用@Bean注解注释的类)存储用户自定义的Bean,在初始化Bean时,又会将其转换为RootBeanDefinition。