1. Package Scan + Component Label Comments
The following comments are used, mainly for classes written by you
- @Controller
- @Service
- @Repository
- @Component
- @ComponentScan
Reference resources spring Annotation Development: ComponentScan Component Scan
2. Use bean annotations
Main usage scenario: Import components from third-party packages with annotations:
- @Bean
Reference resources: spring Annotation Development: Configuration&Bean
3. Use the @Import comment
- Usage: @Import (component to be imported into container); this component is registered automatically in container
- bean's id defaults to the class name
- Example: @Import(value = {Person.class})
actual combat
1. Create a new maven project and add the following dependencies
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency>
2. Create a new entity Person
package com.yefengyu.annotation.bean; public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
3. Create a new configuration class (focus)
package com.yefengyu.annotation.config; import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*; @Configuration @Import(Person.class) public class MainConfig { }
4. Test Code
public static void main(String[] args) { ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class); String[] names = ctx.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } Person person1= (Person)ctx.getBean(Person.class); //bean Of id The default is the class name Person person2= (Person)ctx.getBean("com.yefengyu.annotation.bean.Person"); }
4. Use ImportSelector
ImportSelector is used with Import: Write a class to implement the ImportSelector interface MyImportSelector, and then add MyImportSelector to Import, then the MyImportSelector custom logic returns the components that need to be imported and is added to the container.
Using the code in the third section above, we re-added a class that has nothing, and now we're trying to register it in a container using ImportSelector.
package com.yefengyu.annotation.bean; public class Car { }
1. Write MyImportSelector to implement the ImportSelector interface, override the selectImports method, and return an array in which each string is the full class name of the component to be imported into the container.
package com.yefengyu.annotation; import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; //Custom logic returns components that need to be imported public class MyImportSelector implements ImportSelector { //The return value is the full class name of the component to be imported into the container @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"com.yefengyu.annotation.bean.Car"}; } }
2. Modify the MainConfig configuration class and use the Import annotation to add the MyImportSelector class. Note the red section below.
package com.yefengyu.annotation.config; import com.yefengyu.annotation.MyImportSelector; import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*; @Configuration @Import({Person.class, MyImportSelector.class}) public class MainConfig { }
3. Test, also use the test code above, you can see that the printed results are:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
com.yefengyu.annotation.bean.Person
com.yefengyu.annotation.bean.Car
4. There is a lot of information about the parameter AnnotationMetadata in the public String[] selectImports (AnnotationMetadata annotation Metadata) method to help filter the components to be registered.
5. Use ImportBeanDefinitionRegistrar
As with ImportSelector, define a class that implements the ImportBeanDefinitionRegistrar interface, override its methods, and manually register components.
1. Set a class as the component to be registered
package com.yefengyu.annotation.bean; public class Alarm { }
2. Implement the ImportBeanDefinitionRegistrar interface to manually register components
package com.yefengyu.annotation; import com.yefengyu.annotation.bean.Alarm; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { beanDefinitionRegistry.registerBeanDefinition("alarm",new RootBeanDefinition(Alarm.class)); } }
beanDefinitionRegistry.registerBeanDefinition("alarm",new RootBeanDefinition(Alarm.class));
The first parameter is the component name.
The second parameter is the definition of the type of component to be registered.
AnnotationMetadata is similar to the previous section.BeanDefinitionRegistry has many features:
3. Modify the MainConfig configuration class and use the Import annotation to add the MyImportBeanDefinitionRegistrar class. Note the red section below.
package com.yefengyu.annotation.config; import com.yefengyu.annotation.MyImportBeanDefinitionRegistrar; import com.yefengyu.annotation.MyImportSelector; import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*; @Configuration @Import({Person.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class}) public class MainConfig { }
4. Test, also use the test code above, you can see that the printed results are:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
com.yefengyu.annotation.bean.Person
com.yefengyu.annotation.bean.Car
alarm
6. Use FactoryBean
1. First create a component to be added to the container
package com.yefengyu.annotation.bean; public class Event { }
2. Create a FactoryBean defined by Spring
package com.yefengyu.annotation; import com.yefengyu.annotation.bean.Event; import org.springframework.beans.factory.FactoryBean; //Create a Spring Defined FactoryBean public class EventFactoryBean implements FactoryBean<Event> { //Return a Event Object, which is added to the container @Override public Event getObject() throws Exception { return new Event(); } @Override public Class<?> getObjectType() { return Event.class; } //Is it a singleton? //true: this bean Is a single instance, keeping a copy in a container //false: Multiple instances, each acquisition creates a new bean; @Override public boolean isSingleton() { return true; } }
3. Modify the configuration class and note the code below in the bean comment
package com.yefengyu.annotation.config; import com.yefengyu.annotation.EventFactoryBean; import com.yefengyu.annotation.MyImportBeanDefinitionRegistrar; import com.yefengyu.annotation.MyImportSelector; import com.yefengyu.annotation.bean.Person; import org.springframework.context.annotation.*; @Configuration @Import({Person.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class}) public class MainConfig { @Bean public EventFactoryBean eventFactoryBean() { return new EventFactoryBean(); } }
4. Modify the test code as follows:
package com.yefengyu.annotation; import com.yefengyu.annotation.bean.Person; import com.yefengyu.annotation.config.MainConfig; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class); String[] names = ctx.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } //test EventFactoryBean Object eventFactoryBean = ctx.getBean("eventFactoryBean"); System.out.println("bean The type of is:" + eventFactoryBean.getClass()); Object factoryBean = ctx.getBean("&eventFactoryBean"); System.out.println("bean The type of is:" + factoryBean.getClass()); } }
5. The results are as follows:
mainConfig com.yefengyu.annotation.bean.Person com.yefengyu.annotation.bean.Car eventFactoryBean alarm bean The type of is:class com.yefengyu.annotation.bean.Event bean The type of is:class com.yefengyu.annotation.EventFactoryBean
Summary:
- The default is the object created by the factory bean calling getObject
ctx.getBean("eventFactoryBean");
- To get the factory Bean itself, we need to precede the id with an &
ctx.getBean("&eventFactoryBean");