<> I annotated almost every sentence of code , Hope to help

<>BeanDefinition, There are beanName and beanClass, Then it can be encapsulated into this class
@Data @AllArgsConstructor @NoArgsConstructor public class BeanDefinition {
private String beanName; private Class beanClass; }
<> The most important class MyAnnotationConfigApplicationContext

In his constructor , Let's start with the name of the package he passed in , Scan all classes in this package once
Set<BeanDefinition> beanDefinitions = findBeanDefinitions(pack);
<>findBeanDefinitions function

First, he scans all classes under the package , Then get these classes , I'm going to traverse , Find the annotated class , If I add this annotation , The returned value is not null(Component
componentAnnotation =
clazz.getAnnotation(Component.class)), Next words , Determine whether there is a custom beanName bar , If not , I'll change it for him
// That means I wrote it directly component Just notes , No name was given later , Then I'll give him a name // Name words , I'll kill the one in front of the full class name
// Again Account Change to account this look , Comparative norms if ("".equals(beanName)){ String packageName =
clazz.getPackage().getName(); packageName += "."; String clazzName = clazz.
getName(); clazzName = clazzName.replaceAll(packageName,""); beanName =
clazzName.substring(0,1).toLowerCase()+clazzName.substring(1); }
Now I can beanName And the resulting class is encapsulated into the previously written BeanDefinition Yes , Then put it in the collection , Why gather , Because it's going to be heavy .
//beanDefinitions The collection is placed in the BeanDefinition object
//BeanDefinition Inside field have bean Name and class of , Now wrap it and put it into the collection // Why choose set, It's because I'm going to be heavy , One is enough
beanDefinitions.add(new BeanDefinition(beanName,clazz));
<> The following is the complete function code
public Set<BeanDefinition> findBeanDefinitions(String pack){ Set<BeanDefinition
> beanDefinitions = new HashSet<>(); // Get all classes under the package Set<Class<?>> classes = MyTools
.getClasses(pack); // Traverse these classes , Find the annotated class Iterator<Class<?>> iterator = classes.
iterator(); while (iterator.hasNext()){ Class<?> clazz = iterator.next();
// Return the corresponding annotation Class object Component componentAnnotation = clazz.getAnnotation(Component.
class); if (componentAnnotation!=null){ // obtain component Annotation value String beanName =
componentAnnotation.value(); // That means I wrote it directly component Just notes , No name was given later , Then I'll give him a name
// Name words , I'll kill the one in front of the full class name // Again Account Change to account this look , Comparative norms if ("".equals(beanName)){ String
packageName= clazz.getPackage().getName(); packageName += "."; String clazzName
= clazz.getName(); clazzName = clazzName.replaceAll(packageName,""); beanName =
clazzName.substring(0,1).toLowerCase()+clazzName.substring(1); }
//beanDefinitions The collection is placed in the BeanDefinition object
//BeanDefinition Inside field have bean Name and class of , Now wrap it and put it into the collection // Why choose set, It's because I'm going to be heavy , One is enough
beanDefinitions.add(new BeanDefinition(beanName,clazz)); } } return
beanDefinitions; }
Find all bean After putting it into the collection , What's next , Just put it in ioc Inside the container ,ioc The container is used here
private Map<String,Object> ioc = new HashMap<>();

Next, take mine out of the collection BeanDefinition, Then take them out separately beanName and beanCLass, By class object getConstructor() Method to obtain the constructor (Constructor) Object and call its newInstance() Method to create an object .
Object object = clazz.getConstructor().newInstance();
clazz.getDeclaredFields() Get all the fields , Traverse all fields , Old judgment added @Value Annotated fields
Make it after you get the field name set method
String value = valueAnnotation.value(); // Get the field name String fieldName =
declaredField.getName(); // To do this field set method String methodName = "set" +fieldName.
substring(0,1).toUpperCase()+fieldName.substring(1); Method method = clazz.
getMethod(methodName,declaredField.getType());
To complete the type assignment , I have to change the type , Otherwise, you will report an error directly at that time , type mismatch
switch (declaredField.getType().getName()) { case "java.lang.Integer": val =
Integer.parseInt(value); break; case "java.lang.String": val = value; break;
case "java.lang.Float": val = Float.parseFloat(value); break; }
method.invoke(“ The object entity to which the name of the method to call belongs ”, Parameter value of method );
method.invoke(object,val);
Put it in when you're done ioc Container , use beanName De correspondence
ioc.put(beanName,object);
<> The code of the function
public void createBean(Set<BeanDefinition> beanDefinitions){ Iterator<
BeanDefinition> iterator = beanDefinitions.iterator(); while (iterator.hasNext()
) { BeanDefinition beanDefinition = iterator.next(); // I take out my class from my encapsulated object Class
clazz= beanDefinition.getBeanClass(); // Take mine out of my encapsulated object beanName String beanName =
beanDefinition.getBeanName(); try {
// By class object getConstructor() Method to obtain the constructor (Constructor) Object and call its newInstance() Method to create an object Object
object= clazz.getConstructor().newInstance(); // Get all fields in this class Field[]
declaredFields= clazz.getDeclaredFields(); for (Field declaredField :
declaredFields) { //getAnnotation(), If this is not the case , Just return null Value valueAnnotation =
declaredField.getAnnotation(Value.class); if (valueAnnotation!=null){ String
value= valueAnnotation.value(); // Get the field name String fieldName = declaredField.
getName(); // To do this field set method String methodName = "set" +fieldName.substring(0,1).
toUpperCase()+fieldName.substring(1); Method method = clazz.getMethod(methodName
,declaredField.getType()); // Complete data type conversion Object val = null; // Get the name of the data type , To complete the type assignment
switch (declaredField.getType().getName()) { case "java.lang.Integer": val =
Integer.parseInt(value); break; case "java.lang.String": val = value; break;
case "java.lang.Float": val = Float.parseFloat(value); break; } // Incoming value
//method.invoke(" The object entity to which the name of the method to be called belongs ", Parameter value of method ); method.invoke(object,val); } }
// Put it in when you're done ioc Container ioc.put(beanName,object); } catch (InstantiationException e) { e.
printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }
catch (InvocationTargetException e) { e.printStackTrace(); } catch (
NoSuchMethodException e) { e.printStackTrace(); } } }
<> It's auto load's turn

The same as usual , Pass it on or gather , Traverse all fields at once , See if there's any @Authwired Annotated , See if it's for null
AutoWired annotation = declaredField.getAnnotation(AutoWired.class);
If you find it , That's where the annotation is added , Then I have to find out if there's anything in it @Qualifier Annotated
Qualifier qualifier = declaredField.getAnnotation(Qualifier.class);
If any , Then I have to pass this bean Go by your name ioc Take out the container
Next, get the field name, method and so on
String beanName = qualifier.value(); // adopt bean Go by your name ioc Inside the container bean take out
//ioc The container I use is hashMap Object bean = getBean(beanName); // Get field name String fieldName =
declaredField.getName(); String methodName = "set" + fieldName.substring(0,1).
toUpperCase() + fieldName.substring(1); Method method = clazz.getMethod(
methodName, declaredField.getType());
//method.invoke(" The object entity to which the name of the method to be called belongs ", Parameter value of method ); // Put the other one bean afferent , Otherwise, print it out null of method
.invoke(object,bean);
<> Complete code of this function
public void autowireObject(Set<BeanDefinition> beanDefinitions){ Iterator<
BeanDefinition> iterator = beanDefinitions.iterator(); while (iterator.hasNext()
){ BeanDefinition beanDefinition = iterator.next();
// Because of this beanDefinition Inside the object , There is one beanName And one BeanClass( Put class ) Class clazz =
beanDefinition.getBeanClass(); // Take out all the fields of this class Field[] declaredFields = clazz.
getDeclaredFields(); for (Field declaredField : declaredFields) {
// See if this field has AutoWired This annotation AutoWired annotation = declaredField.getAnnotation(
AutoWired.class); if (annotation!=null){ // See if there's any Qualifier Annotation of this custom name Qualifier
qualifier= declaredField.getAnnotation(Qualifier.class); if (qualifier!=null){
// I use Qualifier Custom name //byName try { String beanName = qualifier.value();
// adopt bean Go by your name ioc Inside the container bean take out //ioc The container I use is hashMap Object bean = getBean(beanName);
// Get field name String fieldName = declaredField.getName(); String methodName = "set" +
fieldName.substring(0,1).toUpperCase() + fieldName.substring(1); Method method =
clazz.getMethod(methodName, declaredField.getType()); Object object = getBean(
beanDefinition.getBeanName()); // Incoming value
//method.invoke(" The object entity to which the name of the method to be called belongs ", Parameter value of method ); // Put the other one bean afferent , Otherwise, print it out null of method
.invoke(object,bean); } catch (NoSuchMethodException e) { e.printStackTrace(); }
catch (IllegalAccessException e) { e.printStackTrace(); } catch (
InvocationTargetException e) { e.printStackTrace(); } }else{ //byType } } } } }
<> Full code for this class
```java public class MyAnnotationConfigApplicationContext { private Map<String,
Object> ioc = new HashMap<>(); public MyAnnotationConfigApplicationContext(
String pack){ // Traversal package , Returns all target classes Set<BeanDefinition> beanDefinitions =
findBeanDefinitions(pack); Iterator<BeanDefinition> iterator = beanDefinitions.
iterator(); // Create from raw materials Bean createBean(beanDefinitions); // Automatic loading autowireObject(
beanDefinitions); } public void autowireObject(Set<BeanDefinition>
beanDefinitions){ Iterator<BeanDefinition> iterator = beanDefinitions.iterator()
; while (iterator.hasNext()){ BeanDefinition beanDefinition = iterator.next();
// Because of this beanDefinition Inside the object , There is one beanName And one BeanClass( Put class ) Class clazz =
beanDefinition.getBeanClass(); // Take out all the fields of this class Field[] declaredFields = clazz.
getDeclaredFields(); for (Field declaredField : declaredFields) {
// See if this field has AutoWired This annotation AutoWired annotation = declaredField.getAnnotation(
AutoWired.class); if (annotation!=null){ // See if there's any Qualifier Annotation of this custom name Qualifier
qualifier= declaredField.getAnnotation(Qualifier.class); if (qualifier!=null){
// I use Qualifier Custom name //byName try { String beanName = qualifier.value();
// adopt bean Go by your name ioc Inside the container bean take out //ioc The container I use is hashMap Object bean = getBean(beanName);
// Get field name String fieldName = declaredField.getName(); String methodName = "set" +
fieldName.substring(0,1).toUpperCase() + fieldName.substring(1); Method method =
clazz.getMethod(methodName, declaredField.getType()); Object object = getBean(
beanDefinition.getBeanName()); // Incoming value
//method.invoke(" The object entity to which the name of the method to call belongs ", Parameter value of method ); // Put the other one bean afferent , Otherwise, print it out null of method
.invoke(object,bean); } catch (NoSuchMethodException e) { e.printStackTrace(); }
catch (IllegalAccessException e) { e.printStackTrace(); } catch (
InvocationTargetException e) { e.printStackTrace(); } }else{ //byType } } } } }
public Object getBean(String beanName){ return ioc.get(beanName); }
// Create from collection bean public void createBean(Set<BeanDefinition> beanDefinitions){
Iterator<BeanDefinition> iterator = beanDefinitions.iterator(); while (iterator.
hasNext()) { BeanDefinition beanDefinition = iterator.next(); // I take out my class from my encapsulated object
Class clazz = beanDefinition.getBeanClass(); // Take mine out of my encapsulated object beanName String
beanName= beanDefinition.getBeanName(); try {
// By class object getConstructor() Method to obtain the constructor (Constructor) Object and call its newInstance() Method to create an object Object
object= clazz.getConstructor().newInstance(); // Get all fields in this class Field[]
declaredFields= clazz.getDeclaredFields(); for (Field declaredField :
declaredFields) { //getAnnotation(), If this is not the case , Just return null Value valueAnnotation =
declaredField.getAnnotation(Value.class); if (valueAnnotation!=null){ String
value= valueAnnotation.value(); // Get the field name String fieldName = declaredField.
getName(); // To do this field set method String methodName = "set" +fieldName.substring(0,1).
toUpperCase()+fieldName.substring(1); Method method = clazz.getMethod(methodName
,declaredField.getType()); // Complete data type conversion Object val = null; // Get the name of the data type , To complete the type assignment
switch (declaredField.getType().getName()) { case "java.lang.Integer": val =
Integer.parseInt(value); break; case "java.lang.String": val = value; break;
case "java.lang.Float": val = Float.parseFloat(value); break; } // Incoming value
//method.invoke(" The object entity to which the name of the method to be called belongs ", Parameter value of method ); method.invoke(object,val); } }
// Put it in when you're done ioc Container ioc.put(beanName,object); } catch (InstantiationException e) { e.
printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); }
catch (InvocationTargetException e) { e.printStackTrace(); } catch (
NoSuchMethodException e) { e.printStackTrace(); } } } public Set<BeanDefinition>
findBeanDefinitions(String pack){ Set<BeanDefinition> beanDefinitions = new
HashSet<>(); // Get all classes under the package Set<Class<?>> classes = MyTools.getClasses(pack);
// Traverse these classes , Find the annotated class Iterator<Class<?>> iterator = classes.iterator(); while (
iterator.hasNext()){ Class<?> clazz = iterator.next(); // Returns the corresponding annotation Class object
Component componentAnnotation = clazz.getAnnotation(Component.class); if (
componentAnnotation!=null){ // obtain component Annotation value String beanName =
componentAnnotation.value(); // That means I wrote it directly component Just notes , No name was given later , Then I'll give him a name
// Name words , I'll kill the one in front of the full class name // Again Account Change to account this look , Comparative norms if ("".equals(beanName)){ String
packageName= clazz.getPackage().getName(); packageName += "."; String clazzName
= clazz.getName(); clazzName = clazzName.replaceAll(packageName,""); beanName =
clazzName.substring(0,1).toLowerCase()+clazzName.substring(1); }
//beanDefinitions The collection is placed in the BeanDefinition object
//BeanDefinition Inside field have bean Name and class of , Now wrap it and put it into the collection // Why choose set, It's because I'm going to be heavy , One is enough
beanDefinitions.add(new BeanDefinition(beanName,clazz)); } } return
beanDefinitions; } } ## Required entity class ```java @Component @Data public class Account {
@Value("1") private Integer id; @Value(" Zhang San ") private String name; @Value("22")
private Integer age; @AutoWired @Qualifier("myOrder") private Order order; }
@Data @Component("myOrder") public class Order { @Value("jyu") private String
address; }
<>@Component annotation
// Behind this is type of , This corresponds to the interface , class , enumeration @Target(ElementType.TYPE)
//runtime, Annotations are not only saved to class In the file , even if jvm load class After file , Still exist @Retention(RetentionPolicy.
RUNTIME) public @interface Component { String value() default ""; }
<>@Value annotation
// This corresponds to field of , The corresponding constants are fields and enumerations @Target(ElementType.FIELD)
//runtime, Annotations are not only saved to class In the file , even if jvm load class After file , Still exist @Retention(RetentionPolicy.
RUNTIME) public @interface Value { String value(); }
<>@Qualifier annotation
// This corresponds to field of , The corresponding constants are fields and enumerations @Target(ElementType.FIELD)
//runtime, Annotations are not only saved to class In the file , even if jvm load class After file , Still exist @Retention(RetentionPolicy.
RUNTIME) public @interface Qualifier { String value(); }
<>@AutoWired annotation
// This corresponds to field of , The corresponding constants are fields and enumerations @Target(ElementType.FIELD)
//runtime, Annotations are not only saved to class In the file , even if jvm load class After file , Still exist @Retention(RetentionPolicy.
RUNTIME) public @interface AutoWired { }

Technology