赞
踩
是 Spring 中定义 Bean 的配置元信息接口
属性 | 说明 |
---|---|
Class | Bean 全类名,不能是抽象类或者接口,只能为具体类 |
Name | Bean 的名称或者ID |
Scope | Bean 的作用域(Singleton 或 prototype) |
Constructor arguments | Bean 的构造器参数(依赖注入) |
Properties | Bean 的成员属性(依赖注入) |
Autowiring mode | Bean 自动绑定模式(byName | byType) |
Lazy initialization mode | Bean 懒加载设置 |
Initialization method | Bean 初始化回调方法名称 |
Destruction method | Bean 销毁回调方法名称 |
/** * {@link org.springframework.beans.factory.config.BeanDefinition} 构建示例 * @author felix * @date 2020/12/19 */ public class BeanDefinitionCreationDemo { public static void main(String[] args) { // 1.通过 BeanDefinitionBuilder 构建 // generic 是较为常见的配置 BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class); // 通过属性设置 beanDefinitionBuilder.addPropertyValue("id", 34); beanDefinitionBuilder.addPropertyValue("name", "three"); // 获取 BeanDefinition 实例 AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition(); // 后续也可以继续进行补充 BeanDefinition 并非最终状态 // 2.通过 AbstractBean GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition(); // 设置bean类型 genericBeanDefinition.setBeanClass(User.class); // 通过 MutablePropertyValues 批量操作属性 MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues.add("id", 34) .add("name", "four"); // 通过 set MutablePropertyValues 批量操作属性 genericBeanDefinition.setPropertyValues(propertyValues); } }
<bean name=""/>
/** * 通过 @Component 的方式定义 */ @Component public class Config { /** * 通过 @Bean 的方式定义 */ @Bean(name = {"user", "three"}) public User user() { User user = new User(); user.setName("dudu"); user.setId(22L); return user; } } /** * 通过 @Import 的方式定义 */ @Import(Config.class) public class AnnotationBeanDefinitionDemo { public static void main(String[] args) { // 创建 BeanDefinition 容器 AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(); // 注册 Configuration Class (配置类) annotationConfigApplicationContext.register(AnnotationBeanDefinitionDemo.class); // @Component 需要配合扫描注解 @Import则不需要 annotationConfigApplicationContext.scan("spring/bean/configTest"); // 启动应用上下文 annotationConfigApplicationContext.refresh(); // 通过 Bean 类型获取 Map<String, Config> beansOfType = annotationConfigApplicationContext.getBeansOfType(Config.class); beansOfType.forEach((key,value)->{ System.out.println(key+":"+value); }); User user = annotationConfigApplicationContext.getBean("user", User.class); System.out.println(user); // 显示的关闭 Spring 应用上下文 annotationConfigApplicationContext.close(); } }
BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,BeanDefinitionRegistry)
AnnotatedBeanDefinitionReader#register(Class)
在XML配置元信息中的 name 属性中使用 「,」或「;」来隔开即可
或
<alias name="user" alias="three-user"/>
标签的形式在注解中会使用 AnnotationBeanDefinition
public class User {
private Long id;
private String name;
public static User createUser(){
return new User();
}
}
<bean id="user-by-static-method" class="spring.ioc.overview.domain.User" factory-method="createUser"/>
调用对应实体类的静态构造方法
public interface UserFactory {
default User createUser() {
return User.createUser();
}
}
public class UserFactoryImpl implements UserFactory {}
<bean id="user-by-instance-method" class="spring.bean.factory.UserFactoryImpl" factory-bean="userFactory" factory-method="createUser"/>
<bean id="userFactory" class="spring.bean.factory.UserFactoryImpl"/>
public class UserFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
return User.createUser();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
<bean id="user-by-factory-bean" class="spring.bean.factory.UserFactoryBean"/>
ServiceLoaderFactoryBean
(配置元信息:XML、Java 注解、Java API)AutowireCapableBeanFactory#createBean(Class,int,boolean)
BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
public class DefaultUserFactory implements UserFactory, InitializingBean { /** * 1.基于 @PostConstruct 注解 */ @PostConstruct public void init() { System.out.println("@PostConstruct"); } /** * 基于 @Bean 去指定 initial */ public void initUserFactory() { System.out.println("@Bean(initMethod = initUserFactory)"); } /** * 基于 Spring 官方{@link org.springframework.beans.factory.InitializingBean} 接口实现 */ @Override public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean#afterPropertiesSet()"); } }
方法执行的先后顺序如下
基于自定义指定初始化方法其实是在 AbstractBeanDefinition 去设置的
可以看懂延迟加载与非延迟加载在注册的时候是没有区别的,但是对于依赖查找和依赖注入来说,非延迟加载在应用上下文启动前就加载完成了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。