Spring -- dependency injection or method injection?

Dependency injection

We are Spring - circular dependency Two dependency injection methods of Spring are discussed in

  • Constructor Injection
  • Attribute injection (setter injection also belongs to this)
@Service
public class HelloService {
    /**
     * Attribute injection
     */
    @Autowired
    private BeanFactory beanFactory;
    /**
     * Constructor Injection 
     */
    public HelloService(ApplicationContext applicationContext) {
    }
    /**
     * Attribute injection
     * */
    @Autowired
    public void setEnvironment(Environment environment) {
        System.out.println("");
    }
}

The article on constructor instantiation strategy has been published in Spring source code -- Bean instantiation and Spring instantiation -- who is my candidate Already talked about

So what's the difference between @ Autowired on properties and setter methods? In fact, Spring is the same and an injection element.

AutowiredAnnotationBeanPostProcessor#postProcessProperties this method is called after the bean is instantiated

What are the differences and applicable scenarios between constructor injection and attribute injection?

  • The timing of constructor injection is prior to attribute injection and is strongly dependent
  • For those non essential dependencies, attribute injection is recommended

Method injection

Lookup

The essence of method injection is that Spring inherits your current class, generates subclasses through CGLib, and overrides the methods to be injected.

Maybe it's not clear, so let's take an example

@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrintService {
    private int printCount;
    public void print(String name) {
        System.out.println("hi! " + name + " " + printCount++);
    }
}
@Service
public class HelloService {
    @Autowired
    private PrintService printService;
    public void sayHi(String name) {
        printService.print(name);
    }
}

PrintService is a prototype bean and HelloService is a singleton. My original intention is that a newly created PrintService object can be used every time the sayHi method is called, but it can not be implemented simply by attribute injection or constructor injection.

Perhaps you might think of using ApplicationContext / BeanFactory to get the PrintService in Spring every time you use it. In this way, you can get a newly created instance every time. This is certainly possible, but since the logic is like this, can the framework help us? Of course

@Service
public class HelloService {
    public void sayHi(String name) {
        getPrintService().print(name);
    }
    @Lookup("printService")
    protected PrintService getPrintService(){
        return null;
    }
}

@The method decorated by Lookup must be overridable by subclasses. If beanName is not set to @ Lookup annotation, the bean will be obtained from Spring according to the method return type

public @interface Lookup {
   String value() default "";
}

This code is actually where we are Spring source code -- Bean instantiation and Spring instantiation -- who is my candidate I have encountered it, but I didn't click in to learn more.

If the class of the method modified with @ Lookup is instantiated through the configuration class, this annotation will become invalid. Only bean s instantiated through constructors can be processed by Spring and subclasses can be generated using CGLib.

MethodReplacer

The second is method replacement

 <bean name="replacer" class="springroad.deomo.chap4.MethodReplace"> 
 </bean> 
 <bean name="testBean" class="springroad.deomo.chap4.LookupMethodBean">
  <replaced-method name="test" replacer="replacer"> </replaced-method> 
 </bean> 
 public class LookupMethodBean {
 public void test()
 {
  System.out.println("Original method!");
 }
 }

public class MethodReplace implements MethodReplacer {
 public Object reimplement(Object obj, Method method, Object[] args)
   throws Throwable {
    System.out.println("Method has been replaced!");
  return null;
 }
}

The annotation related to methodreplacement is not found yet, and can only be configured with the original xml

The principle is the same as that of Lookup

Is it very similar to AOP, but it is actually different. Methodreplace can never call back the covered method. It is completely covered, rather than pre and post interception like AOP. Therefore, in the actual business, this method replacement can be used in few places, and the AOP that can use it can do it, or even more flexible than it

That's all for today's article~~

This article is composed of blog one article multi posting platform OpenWrite release!

Tags: Java Back-end

Posted on Sat, 04 Dec 2021 15:19:17 -0500 by jstarkweather