BeanDefinition 描述了什么

BeanDefinition 表示Bean的定义文件,用于描述了Bean的一些属性。比如描述,描述Bean的class类型,作用域scope、lazyInit bean是否懒加载,initMethodName 表示Bean初始化执行的方发,destoryMethod bean销毁时执行的方法等

Spring中定义bean的方式

1、<bean/>

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的其他属性

spring 中普通类怎么使用bean spring常用类_spring 中普通类怎么使用bean

 

BeanDefinitionReader

spring 中普通类怎么使用bean spring常用类_System_02

 

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"));

BeanFactory

Beanactory 表示bean的工厂,BeanFactory负责Bean的创建,并且提供api给使用者获取bean对象。

其中ApplicationContext也是Beanfactory的继承者,其中在Spring中有一个beanFactory功能强大,即是一个beanFactory,又是一个BeanDefinition,这个类就是DefaultListableBeanFactory。

DefaultListableBeanFsactory

spring 中普通类怎么使用bean spring常用类_spring 中普通类怎么使用bean_03

 

ApplicationContext

上面有分析到,ApplicationContext是个接口,实际上也是一个BeanFactory,不过比BeanFactory 更加强大,比如:

  1. HierarchicalBeanFactory:拥有获取父BeanFactory的功能
  2. ListableBeanFactory:拥有获取beanNames的功能
  3. ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
  4. EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
  5. ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
  6. MessageSource:拥有国际化功能

AnnotationConfigApplicationContext

spring 中普通类怎么使用bean spring常用类_spring_04

 

ClassPathXmlApplicationContext

spring 中普通类怎么使用bean spring常用类_后端_05

 

BeanPostProcess

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"));

ExcludeFilter和IncludeFilter

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<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

这些是类的元数据相关的,其中MetadataReader是类元数据的读取器,他的实现有SimpleMetadataReader。

在Spring中通过ASM技术获取类的元数据信息。