While reading this article, spring annotation driven development , there have been two doubts
- 1. Why did we define the MyTypeFilter class without creating its object and how its methods are called? We know that the calling of non static methods must be completed with the help of the object of the class in which the method itself is located. We guess that spring helped us create this class, but when and how to create it, Let's leave a question.
- 2. There are no @ Component and other annotations, but they are also injected into the spring container. What is the reason?
With the above two questions, start to analyze and guess and look at the code:
public class MyTypeFilter implements TypeFilter { public MyTypeFilter() { System.out.println("I was born"); } @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //Gets information about the class currently being scanned ClassMetadata classMetadata = metadataReader.getClassMetadata(); String className = classMetadata.getClassName(); System.out.println("Through custom matching rules--->"+className); if (className.contains("er")) { return true; } return false; } }
@Configuration //Tell Spring that this is a configuration class //@ComponentScan(value = "org.cc") / / equivalent to < context: component scan base package = "org. CC" / > in the xml configuration file @ComponentScans(value = { @ComponentScan(value = "org.cc",includeFilters = { //Custom matching rules. All classes in the org.cc package are matched according to this rule. If they match, they are injected into the container, including the MyTypeFilter class itself @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class}) },useDefaultFilters = false) }) public class MainConfig { //It is equivalent to the < bean > tag in the xml configuration file, which tells the container to register a bean //Previously, the < bean > tag in the xml file had the class type of the bean, so the type of annotation now is, of course, the type of the return value //Previously, the < bean > tag in the xml file had the bean id, but now the annotation method uses the method name as the bean id by default @Lazy @Bean public Person person() { System.out.println("Add to container person"); return new Person("lisi",20); } /** * Now, the following two bean s are registered to the IOC container with conditions: * 1.If the system is windows, register the container ("bill") * 1.If the system is linux, register the container ("linus") * @return */ @Bean("bill") public Person person01() { return new Person("Bill Gates",62); } @Bean("linus") public Person person02() { return new Person("linus",48); } }
First, analyze step 1. After understanding this, you can understand the first problem. This class was instantiated before the spring container was obtained, or its methods cannot be called. No, follow up the source code here
It can be seen that when we define this class, it will be scanned by the annotation scanner of spring to help us create this object, and then use the function of this object. At this time, it has not been put into the container. We can modify the method of MyTypeFilter to verify,
Operation results after modification:
You can see that all objects in the container no longer contain the MyTypeFilter class. As for why mianConfig, person, bill and linus exist in the container, they do not depend on the filter. See the figure below:
The meaning of MyTypeFilter combined with ComponentScan annotation here is that all classes in org.cc package will be scanned and put into the container as long as the class name contains the "er" character. See here, I must understand the above two questions.
I have always wondered when this class should be actively injected and when we can use it without injection. Take MyTypeFilter as an example. We inherit the TypeFilter interface provided by spring. When the program starts, the spring framework needs to use the MyTypeFilter class with the help of its methods (although we wrote it) To determine which classes should be injected into the spring container, that is, this class is used by the spring framework. Naturally, the spring framework helps us instantiate, and then calls the corresponding methods. But, like some of the configuration classes that we integrate redis, we need to tell spring that when you initialize the container, since we are going to use the functions provided by this class after the spring project starts, Give me the whole object of this class. I'll take it later.
In fact, spring's ioc is to do control inversion and hand over objects to spring for management. Most of the contents of this framework are doing this, which needs to be further understood.