BeanDefinition 表示Bean的定义文件,用于描述了Bean的一些属性。比如描述,描述Bean的class类型,作用域scope、lazyInit bean是否懒加载,initMethodName 表示Bean初始化执行的方发,destoryMethod bean销毁时执行的方法等
1、
2、@Bean
3、@Compent(@Controller、@Service、@Repository)
上述称之为神明式定义Bean,除了上述说明的定义方式之外,还有通过代码编程声明一个bean
/**
* @author 浅唱代码
* @date 2021/10/20 9:49 下午
*/
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 还有很多其他的方法,可以设置一个bean的其他属性
AnnotatedBeanDefinitionReader
可以将某个类直接转为beanDefinition,并且解析类上的注解,比如@Scope、@Conditional、@Lazy、@Primary、@DependsOn等
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
这个不是一个beanDefinition,但是它和beanDefinitionReader类型,不同的是,他可以对传入的一个包路径,将包路径下符合条件(比如是否被@Compent注解)的类,都给封装成一个beanDefinition。
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.huhui.study.springstudydeml.definition");
System.out.println(context.getBean("trainingClass"));
Beanactory 表示bean的工厂,BeanFactory负责Bean的创建,并且提供api给使用者获取bean对象。
其中ApplicationContext也是Beanfactory的继承者,其中在Spring中有一个beanFactory功能强大,即是一个beanFactory,又是一个BeanDefinition,这个类就是DefaultListableBeanFactory。
DefaultListableBeanFsactory
ApplicationContext
上面有分析到,ApplicationContext是个接口,实际上也是一个BeanFactory,不过比BeanFactory 更加强大,比如:
HierarchicalBeanFactory:拥有获取父BeanFactory的功能
ListableBeanFactory:拥有获取beanNames的功能
ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
MessageSource:拥有国际化功能
AnnotationConfigApplicationContext
ClassPathXmlApplicationContext
Bean的后置处理器,用于处理在bean的初始化前和初始化后进行一些功能处理。从而干预Bean
/**
* @author 浅唱代码
* @date 2021/10/21 12:47 下午
*/
@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
bean工厂的后置处理器。干预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 浅唱代码
* @date 2021/10/21 12:55 下午
*/
@Component
public class HuHuiBeanFactoryBeanPostProcess implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("加工处理bean工厂");
}
}
FactoryBean
通过BeanPostprocess的后置处理器,能够干预bean的生成,在bean的初始化过程,干预bean。为了能够完全使用我们自己提供的bean,Spring提供了Bean的后置处理器,例如下面的:
package com.huhui.study.springstudydeml.definition;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/**
* @author 浅唱代码
* @date 2021/10/21 9:43 下午
*/
@Component
public class HuHuiFactoryBean implements FactoryBean {
@Override
public Object getObject() {
return new SpecialUser();
}
@Override
public Class> getObjectType() {
return SpecialUser.class;
}
}
使用
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.huhui.study.springstudydeml.definition");
System.out.println(context.getBean("&huHuiFactoryBean"));
includeFilter:表示包含哪些类需要被加载,即使这个类没有加@Compent注解
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 浅唱代码
* @date 2021/10/20 10:07 下午
*/
@Configuration
@ComponentScan(value = "com.huhui.study.springstudydeml.definition",
includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = SpecialUser.class)})
public class AppConfig {
}
excludeFilter:排查那些类不需要被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 浅唱代码
* @date 2021/10/20 10:07 下午
*/
@Configuration
@ComponentScan(value = "com.huhui.study.springstudydeml.definition",
excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = SpecialUser.class)})
public class AppConfig {
}
FilterType 源码
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
}
自定义过滤使用
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 浅唱代码
* @date 2021/10/21 10:39 下午
*/
public class HuhuiTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) {
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
MergedAnnotations annotations = annotationMetadata.getAnnotations();
MergedAnnotation 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是类元数据的读取器,他的实现有SimpleMetadataReader。
在Spring中通过ASM技术获取类的元数据信息。