What does BeanDefinition describe
BeanDefinition refers to the definition file of a Bean, which is used to describe some attributes of a Bean. For example, the description describes the class type of the Bean, whether the scope scope and lazyInit bean are lazy loaded, initMethodName indicates the party issuing the initialization of the Bean, and the method executed when the destrorymethod Bean is destroyed
How bean s are defined in Spring
1,<bean/>
2,@Bean
3,@Compent(@Controller,@Service,@Repository)
The above is called divine definition bean. In addition to the definition method described above, a bean is declared through code programming
/** * @author Shallow singing code * @date 2021/10/20 9:49 afternoon */ public class BeanDefinitionDemo { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition(); beanDefinition.setBeanClass(TrainingClass.class); context.registerBeanDefinition("trainingClass",beanDefinition); System.out.println(context.getBean("trainingClass")); } }
BeanDefinition has many other methods that can set other properties of a bean
BeanDefinitionReader
AnnotatedBeanDefinitionReader
A class can be directly converted to beanDefinition and the annotations on the class can be parsed, such as @ Scope, @ Conditional, @ Lazy, @ Primary, @ DependsOn, etc
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); AnnotatedBeanDefinitionReader beanDefinitionReader = new AnnotatedBeanDefinitionReader(context); beanDefinitionReader.register(TrainingClass.class);
XmlBeanDefinitionReader
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context); xmlBeanDefinitionReader.loadBeanDefinitions("application.xml"); System.out.println(context.getBean("trainingClass"));
classPathBeanDefinitionScanner
This is not a beanDefinition, but it is different from beanDefinitionReader in that it can encapsulate the qualified classes under the package path (such as whether they are annotated by @ compel) into a beanDefinition for an incoming package path.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); scanner.scan("com.huhui.study.springstudydeml.definition"); System.out.println(context.getBean("trainingClass"));
BeanFactory
Beanagery represents a bean factory. BeanFactory is responsible for the creation of beans and provides APIs for users to obtain bean objects.
ApplicationContext is also the successor of beanfactory. In Spring, there is a beanfactory with powerful functions, that is, a beanfactory and a BeanDefinition. This class is DefaultListableBeanFactory.
DefaultListableBeanFsactory
ApplicationContext
According to the analysis above, ApplicationContext is an interface and actually a BeanFactory, but it is more powerful than BeanFactory, such as:
-
Hierarchical BeanFactory: it has the function of obtaining the parent BeanFactory
-
ListableBeanFactory: it has the function of obtaining beanNames
-
Resourcepattern resolver: a resource loader that can obtain multiple resources (file resources, etc.) at one time
-
EnvironmentCapable: you can get the runtime environment (the runtime environment function is not set)
-
ApplicationEventPublisher: has the function of broadcasting events (without the function of adding event listeners)
-
MessageSource: with internationalization function
AnnotationConfigApplicationContext
ClassPathXmlApplicationContext
BeanPostProcess
The post processor of bean is used to process some functions before and after bean initialization. To interfere with bean
/** * @author Shallow singing code * @date 2021/10/21 12:47 afternoon */ @Component public class HuhuiBeanPostProcess implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("trainingClass")){ System.out.println("-- trainingClass before init--"); } return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("trainingClass")){ System.out.println("-- trainingClass after init--"); } return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName); } }
BeanFactoryPostProcessor
The post processor of the bean factory. Interfere with the generation of beanFactory
package com.huhui.study.springstudydeml.definition; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; /** * @author Shallow singing code * @date 2021/10/21 12:55 afternoon */ @Component public class HuHuiBeanFactoryBeanPostProcess implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println("Processing bean factory"); } }
FactoryBean
The post processor of BeanPostprocess can intervene in bean generation and bean initialization. In order to fully use the beans provided by ourselves, Spring provides the post processor of the bean, such as the following:
package com.huhui.study.springstudydeml.definition; import org.springframework.beans.factory.FactoryBean; import org.springframework.stereotype.Component; /** * @author Shallow singing code * @date 2021/10/21 9:43 afternoon */ @Component public class HuHuiFactoryBean implements FactoryBean { @Override public Object getObject() { return new SpecialUser(); } @Override public Class<?> getObjectType() { return SpecialUser.class; } }
use
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); scanner.scan("com.huhui.study.springstudydeml.definition"); System.out.println(context.getBean("&huHuiFactoryBean"));
ExcludeFilter and IncludeFilter
includeFilter: indicates which classes need to be loaded, even if the class is not annotated with @ compel
package com.huhui.study.springstudydeml.definition; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; /** * @author Shallow singing code * @date 2021/10/20 10:07 afternoon */ @Configuration @ComponentScan(value = "com.huhui.study.springstudydeml.definition", includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = SpecialUser.class)}) public class AppConfig { }
excludeFilter: check which classes do not need to be loaded by Spring
package com.huhui.study.springstudydeml.definition; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; /** * @author Shallow singing code * @date 2021/10/20 10:07 afternoon */ @Configuration @ComponentScan(value = "com.huhui.study.springstudydeml.definition", excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = SpecialUser.class)}) public class AppConfig { }
FilterType Source code
public enum FilterType { /** * Filter candidates marked with a given annotation. * @see org.springframework.core.type.filter.AnnotationTypeFilter */ ANNOTATION, /** * Filter candidates assignable to a given type. * @see org.springframework.core.type.filter.AssignableTypeFilter */ ASSIGNABLE_TYPE, /** * Filter candidates matching a given AspectJ type pattern expression. * @see org.springframework.core.type.filter.AspectJTypeFilter */ ASPECTJ, /** * Filter candidates matching a given regex pattern. * @see org.springframework.core.type.filter.RegexPatternTypeFilter */ REGEX, /** Filter candidates using a given custom * {@link org.springframework.core.type.filter.TypeFilter} implementation. */ CUSTOM }
Custom filter usage
HuhuiTypeFilter.class
package com.huhui.study.springstudydeml.definition; import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; import org.springframework.stereotype.Controller; /** * @author Shallow singing code * @date 2021/10/21 10:39 afternoon */ public class HuhuiTypeFilter implements TypeFilter { @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) { AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); MergedAnnotations annotations = annotationMetadata.getAnnotations(); MergedAnnotation<Controller> controllerMergedAnnotation = annotations.get(Controller.class); if(controllerMergedAnnotation != null){ return true; } return false; } }
AppConfig.class
@Configuration @ComponentScan(value = "com.huhui.study.springstudydeml.definition",useDefaultFilters = false, excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM,classes = HuhuiTypeFilter.class)}) public class AppConfig { }
MetadataReader,ClassMetadata, AnnotationMetadata
These are related to class metadata. MetadataReader is the reader of class metadata, and its implementation has SimpleMetadataReader.
Get the metadata information of the class through ASM technology in Spring.