理解BeanDefintion
scan扫描包 --> 解析这个类—验证这个类能不能被实例化,验证通过后–>new(生命周期)
scan扫描完后:
@Configuration(“xxxx”)
@DependsOn(“yyyy”)
@ComponentScan(basePackages = “first”)
这些信息存到BeanDefintion中
可以理解成spring的class文件;
如果我们设计一个人的类:
Person{
age
name
sex…
}
我们java描述一个class
Class{
name,
Field[]
Method[]
}
而BeanDefintion可以理解成spring中的类,我们要描述bean有些什么专属srping的属性;
就是描述这个bean有什么属性,对bean的抽象;
bean{
scope,
name,
automode
}
BeanDefinition常量
void setAutowireCandidate(boolean var1);
设置是否作为自动装配的候选对象;
BeanDefinition所有的属性在xml都可以找到与之对应的标签;
在spring1.0中认为这些配置在代码中可以去完成比如:
例子:
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
applicationContext.register(JavaConfig.class);
GenericBeanDefinition genericBeanDefinition=new GenericBeanDefinition();
genericBeanDefinition.setBeanClass(User.class);
genericBeanDefinition.setScope(“singleton”);
genericBeanDefinition.setAutowireMode(2);
applicationContext.registerBeanDefinition(“xx”,genericBeanDefinition);
applicationContext.refresh();
但是显而易见,这样编写代码是非常不方便,才改成xml,后来xml也不方便才变成了注解来配置;\
容器:
容器包含了singletonObjects,beanDefinitionMap等等很多东西,单例池并不能像之前说的一样就是spring容器,单例池只是容器的一部分,同样的bean定义map也只是容器的一部分;
singletonObjects存在beanFactory中;原型根本不存在单例池中;
例子:
@Configuration
@ComponentScan(basePackages = “two.first”)
public class JavaConfig {
}
@Component
public class User {
}
@Component
@Scope(“prototype”)
public class UserTwo {
}
(beanDefinitionMap和singletonObjects都在beanFacory中;)
//扫描
**this.invokeBeanFactoryPostProcessors(beanFactory);**把bean属性解析成BeanDefintion;
在执行这个方法之前
beanDefinitionMap中只有spring开天辟地的类和JavaConfig 类的BeanDefintion;
总计7个;
执行完这个方法之后:把User,UserTwo加入到了beanDefinitionMap中去了;
BeanFactoryPostProcessor
在扫描完成,类的BeanDefintion加入到beanDefinitionMap中后可以执行这个方法
例子:
我们通过 BeanFactoryPostProcessor,修改了user为UserThree,UserThree我们不加@Component,User加了@Component
我们这边获取UserThree 时没有问题,获取User时报错;
@Component
public class DBeanFactoryPostprocessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition beanService=(GenericBeanDefinition)beanFactory.getBeanDefinition(“user”);
beanService.setBeanClass(UserThree.class);
}
}
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(JavaConfig.class);
UserThree userThree=applicationContext.getBean(UserThree.class);
User user=applicationContext.getBean(User.class);
//验证与生命周期
this.finishBeanFactoryInitialization(beanFactory);
在执行这个方法之前User 与UserTwo并未加入单例池(singletonObjects)中,加入单例池执行完生命周期都是在这个方法完成的;
但是因为UserTwo是原型的,只能在加载时被创建原型,因此不加入单例池中;
BeanDefinition的父接口AttributeAccessor由AbstractBeanDefinition来实现,AbstractBeanDefinition实现了BeanDefinition和其父接口AttributeAccessor
AbstractBeanDefinition实现BeanDefinition了;
AbstractBeanDefinition的父类BeanMetadataAttributeAccessor的父类AttributeAccessorSupport的(真正)实现了AttributeAccessor;
AttributeAccessor(实现类AttributeAccessorSupport)维护了Map<String, Object> attributes = new LinkedHashMap(0);
这个类提供了对BeanDefinition元数据操作的API;比如我们要描述一个类时,发现spring本身拥有的描述不够用了,这时我们可以通过这个api增加一些额外属性来描述类;
BeanMetadataElement也是由AbstractBeanDefinition实现的
AbstractBeanDefinition继承BeanMetadataAttributeAccessor(真正)实现了BeanMetadataElement的唯一的方法Object getSource();方法;这个方法就是存了类所存在的路径;