spring 源码系列(四)spring中的重要类介绍

目录

一、BeanDefinition

二、BeanFactory和FactoryBean

BeanFactory

FactoryBean

三、BeanFactoryPostProcessor

BeanDefinitionRegistryPostProcessor

四、BeanPostProcessor

总结


spring源码非常负责,如果想阅读好spring源码,那么一些重要类必须弄懂是干什么的,下面就来介绍以下spring中的重要类

一、BeanDefinition

说到BeanDefinition,就要说到java的核心思想了,万物皆对象。众所周知,java是面向对象的编程语言,所有的事务都可以用一个对象来描述,jdk提供了用来描述类的类Class,spring为了能更好的描述bean,也提供了一个类,那就是BeanDefinition。简而言之,BeanDefinition就是用来描述bean的类。

/**
 *
 * BeanDefinition用来描述bean的类,该实例具有属性值。
 *
 */
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	/**
	 * 单例
	 * 
	 */
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

	/**
	 * 原型即多例
	 * 
	 */
	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;


	/**
	 * 
	 */
	int ROLE_APPLICATION = 0;

	/**
	 * 
	 * ROLE_SUPPORT = 1 表示这个类是用户本身的,是从配置文件中过来的
	 */
	int ROLE_SUPPORT = 1;

	/**
	 *
	 * ROLE_INFRASTRUCTURE = 2 表示这个bean是spring自己的
	 */
	int ROLE_INFRASTRUCTURE = 2;

	/**
	 * 父类的名字
	 */
	void setParentName(@Nullable String parentName);

	@Nullable
	String getParentName();

	/**
	 * bean 的 class name
	 */
	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();

	/**
	 * primary标注,表示优先注入,优先使用
	 */
	void setPrimary(boolean primary);

	boolean isPrimary();

	/**
	 * 工厂名字
	 *
	 */
	void setFactoryBeanName(@Nullable String factoryBeanName);

	@Nullable
	String getFactoryBeanName();

	/**
	 * 工厂方法名字
	 */
	void setFactoryMethodName(@Nullable String factoryMethodName);

	@Nullable
	String getFactoryMethodName();

	/**
	 *
	 * 返回此bean的构造函数参数值。
	 */
	ConstructorArgumentValues getConstructorArgumentValues();

	/**
	 *
	 * 构造方法是否有构造参数
	 * @since 5.0.2
	 */
	default boolean hasConstructorArgumentValues() {
		return !getConstructorArgumentValues().isEmpty();
	}

	MutablePropertyValues getPropertyValues();

	/**
	 * Return if there are property values values defined for this bean.
	 * @since 5.0.2
	 */
	default boolean hasPropertyValues() {
		return !getPropertyValues().isEmpty();
	}

	/**
	 *
	 * spring bean初始化完成调用的方法的名字
	 *
	 */
	void setInitMethodName(@Nullable String initMethodName);

	@Nullable
	String getInitMethodName();

	/**
	 * spring bean销毁前调用的方法的名字
	 */
	void setDestroyMethodName(@Nullable String destroyMethodName);

	@Nullable
	String getDestroyMethodName();

	void setRole(int role);

	int getRole();

	/**
	 *
	 * bean 描述
	 * Set a human-readable description of this bean definition.
	 * @since 5.1
	 */
	void setDescription(@Nullable String description);

	@Nullable
	String getDescription();


	// Read-only attributes

	/**
	 *
	 * 是否是单例
	 */
	boolean isSingleton();

	/**
	 * 是否是原型 即多例
	 */
	boolean isPrototype();

	/**
	 *
	 * 是否是抽象
	 */
	boolean isAbstract();

	@Nullable
	String getResourceDescription();

	@Nullable
	BeanDefinition getOriginatingBeanDefinition();

}

从源码中可以看出BeanDefinition具有多个属性,可以用来描述bean,其中beanClassName可以用来存储bean的class,方便后面通过反射创建对象。scope、lazyInit、autowireCandidate等也都是重要属性。

二、BeanFactory和FactoryBean

有很多人弄不清楚BeanFactory和FactoryBean的区别,BeanFactory是创建bean的工厂,我们常说的spring 容器(存储spring bean的map)就是在BeanFactory中定义的。而FactoryBean是spring提供的一个特殊的bean,通过FactoryBean我们也可以将一个普通class注册到spring容器中。

BeanFactory

	Object getBean(String name) throws BeansException;

	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	Object getBean(String name, Object... args) throws BeansException;

	<T> T getBean(Class<T> requiredType) throws BeansException;

	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

从源码中可以看出BeanFactory提供了很多getBean方法,这个方法就是根据不同的参数来获取bean对象。BeanFactory是一个工厂用来存储和创建bean的。

FactoryBean

FactoryBean是spring提供的一个特殊的bean,实现此接口的bean可以往spring容器中添加一个bean。

示例:

@Component("indexFactoryBean")
public class IndexFactoryBean implements FactoryBean {


	@Override
	public Object getObject() throws Exception {
		IndexDao indexDao = new IndexDao();
		return indexDao;
	}

	@Override
	public Class<?> getObjectType() {
		return IndexDao.class;
	}
}


public class Test {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

		Object indexFactoryBean = context.getBean("indexFactoryBean");
		System.out.println(indexFactoryBean.getClass());
	}
}

执行结果:

indexDao
class com.wangcongming.demo.service.IndexDao

可以发现IndexFactoryBean注册到spring容器中的对象是IndexDao,这就是spring中FactoryBean提供的功能。FactoryBean中getObject()方法可以返回一个对象,spring容器初始化的过程中会将getObject()返回的对象添加到spring容器中。那么如果想获取IndexFactoryBean本身的对象怎么办呢?只需在bean name前加&即可取出

public class Test {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

		Object indexFactoryBean = context.getBean("indexFactoryBean");
		System.out.println(indexFactoryBean.getClass());

		Object indexFactoryBean2 = context.getBean("&indexFactoryBean");
		System.out.println(indexFactoryBean2.getClass());
	}
}

执行结果:

indexDao
class com.wangcongming.demo.service.IndexDao
class com.wangcongming.demo.service.IndexFactoryBean

三、BeanFactoryPostProcessor

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

BeanFactoryPostProcessor 工厂后置处理器,它是在工厂初始化完成之后调用,它可以对bean进行修改,是spring提供的一个扩展点。postProcessBeanFactory()方法将factory传入进去了,可以通过factory进行操作。

BeanDefinitionRegistryPostProcessor

它是BeanFactoryPostProcessor的扩充接口,他扩充了一个方法:

void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

可以看到这个方法将registry传入进来了,这意味着我们可以通过registry向容器中添加bean

四、BeanPostProcessor

bean后置处理器,会在bean初始化完成之后回调该接口的方法。

@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

这两个方法有什么区别呢?  postProcessBeforeInitialization方法会在postProcessAfterInitialization之前回调,值得注意的是postProcessAfterInitialization方法的回调是在所有的BeanPostProcessor的postProcessBeforeInitialization方法执行完成之后。

总结

执行时机
BeanDefinition读取bean时,就会使用,生成对应的BeanDefinition对象
BeanPostProcessorbean对象创建完成,还未放入容器中时执行
BeanFactoryPostProcessor工厂初始化完成之后,在bean被创建成对象之前执行
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,会在BeanFactoryPostProcessor之前进行执行
  
  
  

 

 

 

 

 

 

 

 

 

 

注:本文只记录类的功能及作用,不做源码分析

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值