A BeanDefinition is, as the name implies, a Bean definition, so it should contain meta information about the Bean. So that’s what it means. Yeah, that’s what he meant.
All Spring beans generated by the BeanFactory are defined by this.
Let’s see what Spring provides as a BeanDefinition
These are basically the ones shown above. Most of it is made up of ABS. The other is the inner class. We don’t think about,
So let’s learn how to use it.
GenericBeanDefinition
It’s universal.
public class SringApp {
@Data
static class Bean {
String name;
int age;
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(Bean.class);
definition.getPropertyValues().add("name"."xiaoli");
definition.getPropertyValues().add("age".1);
/ / register.
context.registerBeanDefinition("bean1", definition);
context.refresh();
Bean bean = (Bean) context.getBean("bean1"); System.out.println(bean); }}Copy the code
It can be inherited
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(Bean.class);
definition.getPropertyValues().add("name"."xiaoli");
definition.getPropertyValues().add("age".1);
context.registerBeanDefinition("bean1", definition);
GenericBeanDefinition definition2 = new GenericBeanDefinition();
definition2.setParentName("bean1");
// Attributes of bean2 inherit from bean1
context.registerBeanDefinition("bean2", definition2);
context.refresh();
Bean bean1 = (Bean) context.getBean("bean1");
Bean bean2 = (Bean) context.getBean("bean2");
// This is true, but false is returned because only the attributes are inherited.
System.out.println(bean1==bean2);
}
Copy the code
So when did it load. Obviously in context.refresh(); In this method in fresh. Initialize the non – lazy.
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Then enter the
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
// The main process is to register the Bean. It's really easy.
Copy the code
RootBeanDefinition
和 ChildBeanDefinition
These two are paired off. The root node cannot have a parent, and the child node must have a parent. The usage is the same as the one above.
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// root
RootBeanDefinition definition = new RootBeanDefinition();
definition.setBeanClass(Bean.class);
definition.getPropertyValues().add("name"."xiaoli");
definition.getPropertyValues().add("age".1);
context.registerBeanDefinition("bean1", definition);
// child
ChildBeanDefinition definition2 = new ChildBeanDefinition("bean1");
context.registerBeanDefinition("bean2", definition2);
/ / refresh
context.refresh();
Bean bean1 = (Bean) context.getBean("bean1");
Bean bean2 = (Bean) context.getBean("bean2");
System.out.println(bean1==bean2);
}
Copy the code
BeanDefinitionBuilder
tool
A Builder utility class.
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Bean.class);
// lazy means. You only instantiate it when you call get("beanname").
builder.setLazyInit(true);
/ / builder. GetBeanDefinition () is actually a GenericBeanDefinition
context.registerBeanDefinition("bean3", builder.getBeanDefinition());
Copy the code
BeanDefinitionHolder
类
It’s obviously a holder
// Three parameters:
// beanDefinition, bean_name, bean_alias
BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, "bean1".new String[]{"bean2"});
context.registerBeanDefinition(holder.getBeanName(), holder.getBeanDefinition());
for (String alias : Objects.requireNonNull(holder.getAliases())) {
context.registerAlias(holder.getBeanName(), alias);
}
Copy the code
BeanDefinitionParser
类
This interface is an object. Parser is used to parse XML in Spring’s XML configuration. In fact, this return value is useless. If you are interested, take a look at the source code to see why this return value is useless. So returning NULL is fine. You just register with the context.
public interface BeanDefinitionParser {
@Nullable
// Element is a set of tags in XML
// ParserContext is actually the Spring context, because xmlContext is based on this.
BeanDefinition parse(Element element, ParserContext parserContext);
}
Copy the code
BeanDefinitionReader
类
The name, obviously, is a BeanDefinition from somewhere.
There are two of them. XmlBeanDefinitionReader which implements the BeanDefinition interface.
But the AnnotatedBeanDefinitionReader did not.
The main implementation is. The following three methods are also simple. Because you need BeanDefinitionRegistry, and then you just need to get the Resource and register it.
BeanDefinitionRegistry getRegistry(a);
int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
Copy the code
We have the most familiar AnnotatedBeanDefinitionReader at first
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(context);
// SringApp is the configuration class. Context is the register class.
reader.registerBean(SringApp.class);
Copy the code
The XML one, too, just take the source and do it.
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(context);
reader.loadBeanDefinitions("user.xml");
// Refresh.
context.refresh();
// Internal implementation is cumbersome. So find out for yourself.
User bean = context.getBean(User.class);
System.out.println(bean);
Copy the code
ClassPathBeanDefinitionScanner
This is a loader based on the classpath
/ / we call scan method that is invoked ClassPathBeanDefinitionScanner to load.
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.scanner.scan(basePackages);
}
Copy the code
It will scan all components. The default filter is implemented as follows.
Candidate classes are detected through configurable type filters. The default filters include classes that are annotated with Spring's @Component, @Repository, @Service, or @Controller stereotype.Copy the code
BeanDefinitionRegistry
Compare the core, after all, to register BeanDefinition.
Core interface method
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
Copy the code
Our common SpringApplication defaults to a well-implemented register.