Spring配置元信息:Spring存在哪些配置元信息?它们分别用在什么场景?在这里插入图片描述
Spring Bean配置元信息:BeanDefinition
1、GenericBeanDefinition 标准的bean defintion,通用的,除了大部分继承自AbstractBeanDefinition属性外,它还具有 parentName ,来灵活的配置 parent bean defintion
2、RootBeanDefinition
可合并的bean definition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName)
3、AnnotatedBeanDefinition
ScannedGenericBeanDefinition
AnnotatedGenericBeanDefinition
ConfigurationClassBeanDefinition
Spring Bean属性元信息:PropertyValues
/**
* Bean 配置元信息示例
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
* @since
*/
public class BeanConfigurationMetadataDemo {
public static void main(String[] args) {
// BeanDefinition 的定义(声明)
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
beanDefinitionBuilder.addPropertyValue("name", "mercyblitz");
// 获取 AbstractBeanDefinition
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
// 附加属性(不影响 Bean populate、initialize)
beanDefinition.setAttribute("name", "小马哥");
// 当前 BeanDefinition 来自于何方(辅助作用)
beanDefinition.setSource(BeanConfigurationMetadataDemo.class);
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
if (BeanConfigurationMetadataDemo.class.equals(bd.getSource())) { // 通过 source 判断来
// 属性(存储)上下文
String name = (String) bd.getAttribute("name"); // 就是 "小马哥"
User user = (User) bean;
user.setName(name);
}
}
return bean;
}
});
// 注册 User 的 BeanDefinition
beanFactory.registerBeanDefinition("user", beanDefinition);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
}
}
Spring容器配置元信息
基于Java注解装载Spring Bean配置元信息
Spring Bean配置元信息底层实现之XML资源
Spring XML 资源 BeanDefinition 解析与注册
核心API – XmlBeanDefinitionReader
资源 Resource
底层 BeanDefinitionDocumentReader
默认实现DefaultBeanDefinitionDocumentReader
BeanDefinition 解析 BeanDefinitionParserDelegate
(将 Element 转化为 GenericBeanDefinition 然后在封装成 BeanDefinitionHolder,
然后调用DefaultListableBeanFactory#registerBeanDefinition 注册到 beanDefinitionMap)
Spring Bean配置元信息底层实现之Properties资源
Spring Bean配置元信息底层实现之Java注解
基于Java注解装载Spring IoC容器配置元信息
// 将当前类作为 Configuration Class
@ImportResource("classpath:/META-INF/dependency-lookup-context.xml")
@Import(User.class)
@PropertySource("classpath:/META-INF/user-bean-definitions.properties") // Java 8+ @Repeatable 支持
@PropertySource("classpath:/META-INF/user-bean-definitions.properties")
// @PropertySources(@PropertySource(...))
public class AnnotatedSpringIoCContainerMetadataConfigurationDemo {
/**
* user.name 是 Java Properties 默认存在,当前用户:mercyblitz,而非配置文件中定义"小马哥"
* @param id
* @param name
* @return
*/
@Bean
public User configuredUser(@Value("${user.id}") Long id, @Value("${user.name}") String name) {
User user = new User();
user.setId(id);
user.setName(name);
return user;
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 注册当前类作为 Configuration Class
context.register(AnnotatedSpringIoCContainerMetadataConfigurationDemo.class);
// 启动 Spring 应用上下文
context.refresh();
// beanName 和 bean 映射
Map<String, User> usersMap = context.getBeansOfType(User.class);
for (Map.Entry<String, User> entry : usersMap.entrySet()) {
System.out.printf("User Bean name : %s , content : %s \n", entry.getKey(), entry.getValue());
}
// 关闭 Spring 应用上下文
context.close();
}
}