Why does Spring's IOC container use reflection instead of new to create instances?

1. What is reflection?

Reflection is a feature of java. For any class, you can know all the properties and methods of this class, and for any object, you can call any of its methods and properties. This dynamically obtained information and the function of dynamically calling the method of the object are called the reflection mechanism of java language.

Four ways to create objects with reflections

  1. To object Get the form of getClass() object

    Person person=new Student();
    Class person1 = person.getClass();
    
  2. Pass class Forname() create reflection get object

    Class person2 = Class.forName("com.xuan.reflex.Student");
    
  3. Pass the class name Class create reflection get object

    Class <Student> person3 = Student.class;
    
  4. Get object through class loader

    ClassLoader cl = this.getClass.getClassLoader(); // Use ClassLoader of current class 
    Class clazz = cl.loadClass("com.rain.B") // Use the ClassLoader obtained in the first step to load B
    B b = (B)clazz .newInstance(); // A class with B gets an instance of B 
    

2. The difference between reflection and new

  1. Both reflection and new create object instances, but the new object cannot call the private property in the class, while reflection can call the private property in the class!
  2. new belongs to static compilation. It is to determine all modules during compilation. If some functions are added or deleted, it needs to be recompiled. However, the system cannot design it perfectly at one time. When it is found that some functions need to be updated, if static compilation is adopted, the whole program needs to be recompiled once to realize the function update. In other words, users need to uninstall the previous software and reinstall it before recompiling! Such a system is seriously coupled and difficult to expand!
  3. Reflection belongs to dynamic compilation. Determine the type and create the object at runtime, specify the template through reflection, and dynamically pass in the object to be instantiated to the template. Dynamic compilation maximizes the flexibility of Java, reflects the application of polymorphism, and reduces the coupling between classes. The core of ioc in spring is to use reflection decoupling.
  4. Reflection efficiency is low, but after many versions of jdk optimization, the efficiency has been very high!

       

2. Why does IOC use factory + reflection to create objects?

The implementation principle of IoC in Spring is factory mode plus reflection mechanism. If you do not use reflection in factory mode and use new to create objects:

	//Interface fruit
	interface fruit{
	    public abstract void eat();
	} 
	
	//Implementation class Apple 
	class Apple implements fruit{
	     public void eat(){
	         System.out.println("Apple");
	     }
	} 
	
	//Implementation class Orange 
	class Orange implements fruit{
	     public void eat(){
	         System.out.println("Orange");
	     }
	}
	
	//Construct factory class
	//In other words, if we add other instances in the future, we only need to modify the factory class
	class Factory{
	     public static fruit getInstance(String fruitName){
	         fruit f=null;
	         if("Apple".equals(fruitName)){
	             f=new Apple();
	         }
	         if("Orange".equals(fruitName)){
	             f=new Orange();
	         }
	         return f;
	     }
	}
	
	class hello{
	     public static void main(String[] a){
	         fruit f=Factory.getInstance("Orange");
	         f.eat();
	     }
	}

The disadvantage of the above method is that when we add another subclass, we need to modify the factory class. If we add too many subclasses, there will be a lot of changes. The factory mode is realized by reflection mechanism:

	interface fruit{
	     public abstract void eat();
	}
	
	class Apple implements fruit{
	public void eat(){
	         System.out.println("Apple");
	     }
	}
	
	class Orange implements fruit{
	public void eat(){
	        System.out.println("Orange");
	    }
	}
	
	class Factory{
	    public static fruit getInstance(String ClassName){
	        fruit f=null;
	        try{
	        	//Use reflection in the factory!
	            f=(fruit)Class.forName(ClassName).newInstance();
	        }catch (Exception e) {
	            e.printStackTrace();
	        }
	        return f;
	    }
	}
	class hello{
	    public static void main(String[] a){
	        fruit f=Factory.getInstance("Reflect.Apple");
	        if(f!=null){
	            f.eat();
	        }
	    }
	}

Using reflection in this way, no matter how many fruit instances we create, there is no need to modify the factory template generated by reflection, which effectively reduces the system coupling!

The working mode of IOC container is regarded as the sublimation of factory mode. IOC container can be regarded as a factory. The objects to be produced in this factory are defined in the configuration file, and then the corresponding objects are generated according to the class name given in the configuration file by using the reflection mechanism provided by the programming language. From the perspective of implementation, IOC changes the object generation code previously written in the factory method to be defined by the configuration file, that is, it separates the factory and object generation independently, in order to improve flexibility and maintainability.

Keywords: Spring

Added by hagman on Tue, 01 Feb 2022 23:03:04 +0200