This article summarizes how to use annotations to add objects to the IOC container management (never ending, it will be updated all the time).
Comment from the author: It's so annoying, so many fucking uses, and then those SpringBoot starter frameworks use whatever they want, which makes it painful to see the understanding of the source code. In fact, I feel that there are many types of ways, but instead lose the specifications and increase the cost of understanding. It's really annoying! ! ! ! ! ! ! ! !
Note: All usage methods come from Spring framework, SpringBoot is not discussed in this article.
@Component + @ComponentScan
First of all, the most commonly used and widely used method to use the stage. The meta annotation extends the same @Controller, @Service, @Repository, etc.
Container bean name: The default is the lowercase first letter of the class name (app)
Recommended usage scenarios: The classes in your own project need to be handed over to Spring management.
@Component public class App { }
@Configuration + @Bean
In fact, @Configuration is also @Component, so you can use @Component. As for why you design this way, you should be able to know the name. You can build your own code through @Bean to build your bean object, and then stuff it into Spring. It can be similar to Spring calling back the method on your @Bean, injecting the objects you define and create into Spring, you can define your own construct initialization, etc.
Container bean name: The default is the corresponding method name (a)
Recommended usage scenarios: For example, if you want to add the object in the introduced jar package, you will generally use this. Also, you want to define the specific process of class generation, which is more flexible.
@Configuration public class AppConfiguration { @Bean public A a() { return new A("junmo", 27); } }
@Import
Before talking about this annotation, please check the official instructions
/** * Used to import one or more <em>component classes</em>, usually the {@link Configuration @Configuration} class. * * <p>Function is similar to the {@code <import/>} element in Spring XML. * Allow import of {@code @Configuration} classes, {@link ImportSelector} and * {@link ImportBeanDefinitionRegistrar} implementation class, as well as ordinary component classes (supported since 4.2, similar to * {@link AnnotationConfigApplicationContext#register} method's function). * * <p>The {@code @Bean} defined in the imported {@code @Configuration} class can be passed * {@link @Autowired} annotation injection. * Developers can choose to inject the bean directly or inject an instance of the configuration class that declares the bean, which facilitates quick navigation of the configuration method in the IDE. * * <p>This annotation can be used directly on the class or as a meta annotation to be used by other annotations. * * <p>If you need to import XML or other resources that are not {@code @Configuration}, you should use * {@link ImportResource @ImportResource} annotation. */ @Target() @Retention() @Documented public @interface Import { /** * Specify the class to import,Including the following categories: * 1. Class marked {@link Configuration @Configuration}. * 2. Class that implements the {@link ImportSelector} interface. * 3. Class implementing the {@link ImportBeanDefinitionRegistrar} interface. * 4. Normal component classes。 */ Class<?>[] value(); }
1. @Import(simple)
@Import({, }) @Configuration public class App { }
As can be seen from the examples here, the usage is relatively simple, and it feels as brainless and fast as @Component. And it supportsbatchoh!
Container bean name: The default is the full class name ()
Recommended usage scenarios: This annotation has an explanation, indicating one or more component classes to be imported, and a bunch of objects can be imported in a simple and quick manner. You can use this. (The premise is that this class is not a class in your project, but a class introduced from outside, and needs to be added to ioc, otherwise @Component can do it too)
shortcoming: Obviously this method is not suitable for building complex object initialization, not as good as @Bean.
2. @Import+Implement the ImportSelector interface (this SpringBoot uses it crazy)
It is obvious that this code can be written and added by yourself at runtime. The advantage of this is that I can choose which objects to add to the ioc, after all, I only recognize the last return String[].
@Import() @Configuration public class App { } public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // importingClassMetadata: This is the annotation on the target class, which is what is the use of all the annotations (@Import, @Configuration) on the above App class? Limited capacity, not yet known haha // Here you can choose some conditions to selectively load if(xxxxxxxxx) { return new String[]{"", ""}; } else { return new String[]{"", ""}; } } } }
Container bean name: The default is the full class name ()
Recommended usage scenarios: It also supports batches. At the same time, you need to use different conditions in your project and selectively load beans. You can use this.
shortcoming: It is obvious that this method is not suitable for building complex object initialization, not as good as @Bean, and it also needs to implement an interface, which is more cumbersome.
3. @Import+Implement ImportBeanDefinitionRegistrar interface
The biggest advantage of this is that you can get the ioc bean registry (BeanDefinitionRegistry), which has many functions, that is, you can do whatever you want in the program.
@Import() @Configuration public class App { } public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) { // This A is your object class BeanDefinition aBeanDefinition = new RootBeanDefinition(); ("Can you define your own bean name", aBeanDefinition); } }
Container bean name: You can define the bean name yourself
Recommended usage scenarios: Comparing the above two, you can get the BeanDefinitionRegistry, you can define the bean name yourself, and you can do some other things.
FactoryBean (non-annotated)
From the first glance, the translation is a factory bean. The meaning is to know that this method can produce bean objects. It actually uses a carrier to produce beans, which itself is also a bean, and its usage is completely different from the above. For example, this is like a factoryBean that puts water out of the curling water.
@Component // Of course, you can also load it into ioc with @Beanpublic class AFactoryBean implements FactoryBean<A> { @Override public A getObject() throws Exception { // It feels like @Bean, you can build your own object and initialize it. return new A("junmo", 27); } @Override public Class<?> getObjectType() { // I don’t understand this, why should I provide this? Not all getObject objects can be obtained, can’t the Class information be obtained? The developer must rewrite the implementation of this method. I don’t understand and don’t know what kind of scenarios will use this method. return ; } @Override // Is this a single case or multiple case setting, which is not within the scope of this article, but you need to know that it can do this public boolean isSingleton() { return (); } }
Container bean name: This one is a bit special. Its bean name will be AFactoryBean in the ioc container, and then the object class you get will indeed be . (It is obvious that it calls the getObject method to produce the object for you, which means why it is called FactoryBean?)
Recommended usage scenarios: Dynamic object creation, different beans are generated according to conditions, proxy classes are created, multiple instances are generated or life cycle management requirements. But I don't think it's much different from @Bean. But many frameworks outside use this method to define beans. There is still a difference, because it will call the getObject method to produce objects, which can take effect after the project is run, and can dynamically generate beans.
Another thing to say: If you want to obtain the AFactoryBean object, you can use it to add "&" in front to get the object. Forget it, this is not important and is generally not very useful (it is easy to understand from the source code below).
public interface BeanFactory { /** * Used to dereference a {@link FactoryBean} instance and distinguish it from * beans <i>created</i> by the FactoryBean. For example, if the bean named * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * will return the factory, not the instance returned by the factory. */ String FACTORY_BEAN_PREFIX = "&"; }
This is the end of this article about the summary of Spring bean registration into a container. For more relevant Spring bean registration into a container, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!