点击关注上方蓝字,阅读更多干货~
为什么需要读懂BeanDefinition
BeanDefiniton与对象的关系
众所周知spring是一个管理bean的容器,那么在此有必要解释java中的对象和spring中的bean这两者的联系;我们的java文件在编译以后会生成class文件,jvm启动的时候会将classpath目录下的class文件加载到方法区,当项目中需要实例化某个类时就会根据类的符号引用找到方法区中的类文件元数据,也就是如下图中的User类中我们定义的id、name等等字段的类文件,此时可以将符号引用转换成实际引用,创建对象以后保存在堆上(当然从操作系统的角度来看,其实还是虚拟地址而不是真实的物理地址)。
public class GeneralObject {
private class sourceObject;
private String objectName;
private File classFile;
}
BeanDefinition的重要属性
与BeanDefinition的接口
BeanDefinition接口
package org.springframework.beans.factory.config;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;
import org.springframework.lang.Nullable;
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
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();
boolean isPrimary();
void setFactoryBeanName(@Nullable String factoryBeanName);
@Nullable
String getFactoryBeanName();
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
void setDestroyMethodName(@Nullable String destroyMethodName);
@Nullable
String getDestroyMethodName();
void setRole(int role);
int getRole();
void setDescription(@Nullable String description);
@Nullable
String getDescription();
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
@Nullable
String getResourceDescription();
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
与Spring中bean的生命周期有关的属性和方法
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
//这两个很好理解,就是在Spring的bean工厂中定义的两个字符串常量
//SCOPE_SINGLETON的值为singleton,SCOPE_PROTOTYPE的值为prototype
boolean isSingleton();
boolean isPrototype();
void setScope(@Nullable String scope);@NullableString getScope();//与scope相关的api
1. 懒加载
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
2. DependsOn
void setDependsOn(@Nullable String... dependsOn);
@Nullable
String[] getDependsOn();
3. 生命周期回调方法
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
void setDestroyMethodName(@Nullable String destroyMethodName);
@Nullable
String getDestroyMethodName();
2)直接为bean的BeanDefinition赋值:
GenericBeanDefinition testBean = (GenericBeanDefinition)beanFactory.getBeanDefinition("testBean");
testBean.setDestoryMethodName("myDestory");
exposedObject = initializeBean(beanName,exposedObject,mbd); ...invokeInitMethods(beanName,wrappedBean,mbd); ...((InitializingBean)bean).afterPropertiesSet(); ...invokeCustomInitMethod(beanName,bean.mbd);
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
boolean isPrimary();
public class UserController {
@Autowired
private UserService userService;
}
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
beanDefinition1.getPropertyValues().add("name","tom");
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new Test1(),Test1.class.getName());
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
7. ParentBeanDefinition
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
boolean isAbstract();
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setBeanClass(ParentBean.class);
rootBeanDefinition.getPropertyValues.add("name","child");
rootBeanDefinition.getPropertyValues.add("type","parent-type");
//注册BeanDefinition
ac.registerBeanDefinition("parent",rootBeanDefinition);
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(ChildBean.class);
beanDefinition.getPropertyValues.().add("name","child-type");
beanDefinition.setParentName("parent");
ac.registerBeanDefinition("child",beanDefinition);
ac.register(AppCOnfig.class);
ac.refresh();
System.out.println(ac.getBean(ChildBean.class).getType);
void setFactoryBeanName(@Nullable String factoryBeanName);
@Nullable
String getFactoryBeanName();
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
9. 其他
//可以在一个类上声明Description注解,里面可以传入对这个bean的描述,用处不大
void setDescription(@Nullable String description);
@Nullable
String getDescription();
//用来描述当前bean的class文件的路径
@Nullable
String getResourceDescription();
resourceDescription的打印信息
public interface AttributeAccessor {
void setAttribute(String name, @Nullable Object value);
@Nullable
Object getAttribute(String name);
@Nullable
Object removeAttribute(String name);
boolean hasAttribute(String name);
String[] attributeNames();
}
@Configuration
@ComponentScan("com")
public class AopConfig {
@Bean
public CycleA cycleA() {
return new CycleA();
}
@Bean
public CycleB cycleB() {
CycleA cycleA = cycleA();
//do something with cycleA ...
return new CycleB();
}
}
@Component
@ComponentScan("com")
public class AopConfig {
@Bean
public CycleA cycleA() {
return new CycleA();
}
@Bean
public CycleB cycleB() {
CycleA cycleA = cycleA();
//do something with cycleA ...
return new CycleB();
}
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
System.out.println(context.getBean(AppConfig.class));
com.config.AppConfig$$EnhancerBySpringCGLIB$$33f14ba8@588df31b
com.config.AppConfig@6ee52dcd
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE,Boolean.TRUE);
public interface BeanMetadataElement {
Object getSource();
}
BeanDefinition的相关实现类
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
GenericBeanDefinition is a one-stop shop for standard bean definition purposes.
Like any bean definition, it allows for specifying a class plus optionally
constructor argument values and property values. Additionally, deriving from a parent bean definition can be flexibly configured through the "parentName" property.
package org.springframework.beans.factory.support;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
@SuppressWarnings("serial")
public class GenericBeanDefinition extends AbstractBeanDefinition {
@Nullable
private String parentName;
public GenericBeanDefinition() {
super();
}
public GenericBeanDefinition(BeanDefinition original) {
super(original);
}
@Override
public void setParentName(@Nullable String parentName) {
this.parentName = parentName;
}
@Override
@Nullable
public String getParentName() {
return this.parentName;
}
@Override
public AbstractBeanDefinition cloneBeanDefinition() {
return new GenericBeanDefinition(this);
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof GenericBeanDefinition)) {
return false;
}
GenericBeanDefinition that = (GenericBeanDefinition) other;
return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other));
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Generic bean");
if (this.parentName != null) {
sb.append(" with parent '").append(this.parentName).append("'");
}
sb.append(": ").append(super.toString());
return sb.toString();
}
}
@Bean
public BeanTest beanTest() {
return new BeanTest();
}
BeanDefinition definition = ac.getBeanDefinition("beanTest");
//打印结果为class org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition
System.out.println(definition.getClass());
//打印结果为 null
System.out.println(definition.getBeanClassName());
private final AnnotationMetadata annotationMetadata;
private final MethodMetadata factoryMethodMetadata;
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.register(AppConfig.class);
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
本文作者
佳成,来自缦图互联网中心中台团队。
长按识别二维码
查看更多精彩
-----END-----