The interview questions

From the bottom of your soul: talk about your understanding of Spring;

The inner workings of the confused job seeker: What? What are the specific problems? What, interviews don’t go by the book anymore? How am I supposed to answer a big question like that?

Dumbfounded candidate answers: Uh… Uh… well… Uh… I don’t know…

Why do interviewers ask this question?

Now there is no denying the fact that most of the way of interview questions are such, striking similarities, the interviewer is like throwing a problem, see how deep you can speak, take an examination of is you to the depth and breadth of this technology, the depth is do you know about the underlying technology, range is the range of application of this technology, as well as the direction. At this time, a bar master students will ask: “Why do you want to know these so low-level things? As long as I know how to use it, I always build a rocket during the interview, but LET me turn the screws in the actual work. “, although that is true, but you need to consider that everyone can use this thing, and not only you can, since everyone can things, if you reflect your value? Both Xiao Hong and Xiao Ming can use Spring, but Xiao Ming knows its underlying implementation mechanism and principle. It should be noted that the depth of your answer determines your salary and treatment, which is very important. So how should we answer this question? In fact, it is very simple, first sort out the general context, and then explain in depth one by one; This is what I’ve been doing since I started blogging this year, breaking it down from the beginning, with code and flow charts.

As a programmer, if you want to develop to the direction of experts, you must understand the idea of programming, the underlying implementation principle of the algorithm, the code is only the second, because the principle is one, the implementation of a variety of ways, an interface, let ten thousand people to write the implementation of the ten thousand people will not be the same; That’s how important ideas are.

Spring IOC

Ioc is called inversion of control, or dependency injection (DI), which is actually another word for IOC.

1. Who controls whom? In the past, object creation and destruction were controlled by the user. With IOC, object creation and destruction are controlled by the container, and the user can only focus on business needs.

2. What is inversion? : Since it is called reverse, there must be positive turn, positive turn is actually the object to find instances, and reverse on the other hand, let instances to find objects; How do I find it? Through containers, of course!

3. Who depends on whom? : In the Spring project, objects are understood as beans, or Bean objects. There is a dependency between the Bean and the container. Bean objects are created by the container, just as children depend on their parents. Parents are containers;

4.Who injected whom?The bean object is injected through the container, and the process is automated, that is, the container will automatically find the type instance matching the bean object to inject into the object;

The spring IOC loading process

After learning about inversion of control and dependency injection, let’s take a look at the loading process of IOC. The whole loading process of IOC is shown in the following figure.

BeanDefinitionReader (BeanDefinition object); BeanDefinitionReader (BeanDefinition object); BeanDefinitionReader (BeanDefinition object) Just like in a factory, the raw material is ready, but it hasn’t been produced yet, the raw material is the beanDefinition, and the production is the instantiation

BeanDefinition and full BeanDefinition can be modified by implementing the BeanFactoryPostProcessor interface through a single post-enhancer. There can be multiple post-enhancers. You simply implement multiple BeanFactoryPostProcessor interfaces in different classes and they will be executed multiple times, like this:

package com.Spring.Boot.init;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/** * extension method -- post-enhancer (can modify bean definition information) */
@Component
public class ExtBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// BeanDefinition studentService = beanFactory.getBeanDefinition("studentService");
        System.out.println("Extension method -- Modifiable beanDefinition definition information"); }}Copy the code

3. Once the BeanDefinition is complete, you can create the object. This process is called the bean’s life cycle, from instantiation to destruction. “Why is object creation and destruction so much trouble? Doesn’t direct reflection instantiate an object? Why is there initialization?” ; First of all, this is a good question. Let’s give our applause to the questioner. What I want to say is that even a normal new object will be instantiated and initialized. Next we will focus on the bean life cycle;

The life cycle of Spring beans

Roughly speaking, the bean life cycle is divided into the following four steps

But actually, there’s a lot going on inside, so let’s look at the detailed flow chart;

How’s that? Did you see a lot of things you’ve never seen before? I seem to know a few, but most of them are not seen, it doesn’t matter if you don’t know, we will explain one by one

Next we will 1, 3, 4 together, because they are in the same interface, can realize InstantiationAwareBeanPostProcessor interface

package com.Spring.Boot.init;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
 
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
 
    // instantiate the prefix
    @Override
    public ObjectpostProcessBeforeInstantiation(Class<? > beanClass,String beanName) throws BeansException {
        
        System.out.println(Are called "postProcessBeforeInstantiation - before the object instantiation call -- -- -- -- -- beanName:" + beanName);
        // Do nothing by default, return null
        return null;
    }
 
    // instantiate after
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("PostProcessAfterInstantiation is called the -- -- -- -- -- -- -- -- -- beanName:" + beanName);
        // Return true by default, do nothing, proceed to the next step
        return true;
    }
    
    // Attribute modification
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        System.out.println("PostProcessPropertyValues is called the -- -- -- -- -- -- -- -- -- beanName:"+beanName);
        // This method can add, modify, delete the bean attribute value;
        / / modify attribute values, if postProcessAfterInstantiation method returns false, this method may not be invoked,
        returnpvs; }}Copy the code

Let’s explain it one by one

1. Instantiate prefixes

Instantiate the front using InstantiationAwareBeanPostProcessor. PostProcessBeforeInstantiation (Class <? > beanClass, String beanName, beanClass, beanName, beanClass, beanName, beanClass, beanName, beanClass, beanName, beanClass, beanName, beanClass Its bottom layer is dynamic proxy AOP technology implementation; And is the first method executed in the bean lifecycle;

Return non-empty: The return value is the Object types, which means we may return values of any type, because this time the target Object is not yet instantiated, so the return value can be used instead of the originally generated Object instances of the target Object, that is to say, if return a non-empty value, then later we need to use this bean, You get the object that you’re returning, so you don’t have to go to the second step to instantiate the object;

Return null: Null is returned by default, so it is returned directly. The doCreateBean method is then called to instantiate the object.

2. Instantiate the object

The doCreateBean method creates the instance using reflection. This is nothing to say, just like a new object, but it is important to note that the object is instantiated, the properties of the object are not set.

3. Instantiate postposition

The method name: InstantiationAwareBeanPostProcessor. PostProcessAfterInstantiation (Object bean, String beanName)

Called after the target object is instantiated, when the object has been instantiated, but the instance properties have not been set, which are null. Because he’s the return value is a factor in deciding to call postProcessPropertyValues method (because there is another factor is MBD getDependencyCheck ());

Returns false: if this method returns false, and do not need to check, then postProcessPropertyValues will be ignored no execution;

Returns true: if you return true, postProcessPropertyValues will be executed

4. Attribute modification

Method name: InstantiationAwareBeanPostProcessor.PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)

This method can modify attribute values, including adding, modifying and deleting operations; If instantiation rear postProcessAfterInstantiation () method returns false, the method will not be called;

5. Assign user attributes

User attributes refer to bean object attributes defined by spring users. Objects such as User, Student, Teacher, UserService, and IndexService are all custom bean objects. Step 5 assigns values to these attributes. Using the AbstractAutowireCapableBeanFactory. PopulateBean assignment () method;

6. Assign container properties

The container properties are actually the container’s own properties, and these properties are native to Spring; To be sure, they are all implementation classes of the Aware interface. There are mainly the following implementation classes, which I have arranged in order of execution.

Let’s see how it works first, and then we’ll explain what each of Aware does. In the code

package com.Spring.Boot.init.aware;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.*;
import org.springframework.context.annotation.ImportAware;
import org.springframework.context.weaving.LoadTimeWeaverAware;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;
import org.springframework.web.context.ServletContextAware;
import javax.servlet.ServletContext;
 
@Component
public class AllAwareInterface  implements BeanNameAware.BeanClassLoaderAware.BeanFactoryAware.EnvironmentAware.EmbeddedValueResolverAware.ResourceLoaderAware.ApplicationEventPublisherAware.MessageSourceAware.ApplicationContextAware.ServletContextAware.LoadTimeWeaverAware.ImportAware {
 
    @Override
    public void setBeanName(String name) {
        // BeanNameAware makes the Bean aware of the Name
        // This method simply returns our current beanName. This interface is more commonly used in spring framework code and should not be recommended in actual development environments
        System.out.println("1 I am BeanNameAware setBeanName method -- parameter: name, content:"+ name);
    }
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("2 I am the setBeanClassLoader method of BeanClassLoaderAware");
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        // Note that the setBeanFactory method is executed twice if the @Configuration annotation is used.
        System.out.println("3 I am the setBeanFactory method of BeanFactoryAware");
    }
    @Override
    public void setEnvironment(Environment environment) {
        System.out.println("4 I am EnvironmentAware's setEnvironment Method");
    }
    @Override
    public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
        System.out.println(5 I am EmbeddedValueResolverAware setEmbeddedValueResolver method ",");
    }
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        System.out.println("6 I am the setResourceLoader method of ResourceLoaderAware");
    }
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("7 I am ApplicationEventPublisherAware setApplicationEventPublisher method");
    }
    @Override
    public void setMessageSource(MessageSource messageSource) {
        System.out.println("8 I am the setMessageSource method of MessageSourceAware");
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("9 I am ApplicationContextAware setApplicationContext method");
    }
    @Override
    public void setServletContext(ServletContext servletContext) {
        System.out.println("10 I'm the setServletContext method for ServletContextAware");
    }
    @Override
    public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) {
        // LTW is an implementation of AOP. This method is used to get objects woven by AOP. The method is classload-time weaving.
        // Most AOP is runtime weaving, i.e. the aspect methods are woven at run time, whereas LTW is woven before class loading, i.e. the class file is woven into the aspect methods before JVM loading
        // Only when using @enableloadtimeWeaving or a Bean implemented by LoadTimeWeaver
        System.out.println("11 I am setLoadTimeWeaver method of LoadTimeWeaverAware");
    }
    @Override
    public void setImportMetadata(AnnotationMetadata annotationMetadata) {
        // This is called only when the @import (xx.class) configuration class is called, which is first in order for all @beans in xx.class.
        System.out.println("12 I am ImportAware setImportMetadata method"); }}Copy the code

The console prints some of the results after starting Spring:

You can see that their output is printed out in order, that’s the standard order; Now let’s see what they do

6.1 BeanNameAware. SetBeanName ()

This method simply returns our current beanName. This interface is mostly used in spring framework code and should not be recommended in actual development environments

6.2 BeanClassLoaderAware. SetBeanClassLoader ()

Get the Bean’s classloader,

6.3 BeanFactoryAware. SetBeanFactory ()

Get the bean factory. The beanFactory allows you to read objects from the IOC container without relying on injection, but the beanFactory itself is injected.

Note that normally we use the @Component annotation. If we use the @Configuration annotation, the setBeanFactory method executes twice;

6.4 EnvironmentAware. SetEnvironment ()

After implementing EnvironmentAware interface override setEnvironment method, the property values configured in the application. Properties, XML, and YML profiles can be obtained during project startup.

6.5 EmbeddedValueResolverAware. SetEmbeddedValueResolver ()

We usually use @ Value the values in the annotations to obtain the properties and yml file, each class should use @ Value also tedious, after realizing EmbeddedValueResolverAware interface is much more convenient. ${} is the same as @value.

@Component   
public class PropertiesUtil implements EmbeddedValueResolverAware {
 
	@Override
	public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {   
     System.out.println(stringValueResolver.resolveStringValue("${logging.file}")); }}Copy the code

6.6 ResourceLoaderAware. SetResourceLoader ()

Spring ResourceLoader provides a unified getResource() method to retrieve external resources through the resource path. Different implementations that load resources or files (such as text files, XML files, properties files, or image files) into the context of a Spring application are, in essence, used to load external resources; The method has an argument: ResourceLoader, which is the ApplicationContext (spring’s context object); Can be directly strong rotation;

package org.crazyit.app.service;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
public class TestBean implements ResourceLoaderAware{
   
    public void setResourceLoader(ResourceLoader resourceLoader) {
        // Can be converted directly to ApplicationContext
        ApplicationContext context = (ApplicationContext) resourceLoader;
 
        System.out.println("6 I am the setResourceLoader method of ResourceLoaderAware"); }}Copy the code

And we can specify different prefixes to create paths to load resources from different locations

6.7 ApplicationEventPublisherAware. SetApplicationEventPublisher ();

ApplicationEventPublisherAware is an event publishing interface, using this interface, our Service has the ability to publish events. After a user is registered, instead of invoking another business Service, a user registration event is published. This interface is called ApplicationListener. If you implement the ApplicationListener interface, you can accept published events. Next, we write an example to simulate published events and listener events.

Create an entity class to store the published event content, StringEvent.java

package com.Spring.Boot.init.listener.eventModel;
import org.springframework.context.ApplicationEvent;
// Event listener
public class StringEvent extends ApplicationEvent {
 
    private String str;
    // constructor
    public StringEvent(Object source) {
        super(source);
        str = source.toString();
    }
    // Get the string
    public String getStr(){
        returnstr; }}Copy the code

Create a publish event class: ExtApplicationEventPublisherAware. Java, realize ApplicationEventPublisherAware interface increases the function of publishing events;

package com.Spring.Boot.init.aware;
 
import com.Spring.Boot.init.listener.eventModel.StringEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
 
/** * Release event */
@Component
public class ExtApplicationEventPublisherAware implements ApplicationEventPublisherAware {
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("Publish event, event object: StringEvent, content: 1234");
        StringEvent stringEvent = new StringEvent("1234");
        / / publishing events, after the release of ApplicationListener. OnApplicationEvent capture () method;
        applicationEventPublisher.publishEvent(stringEvent);  // Publish events}}Copy the code

Create an EventListener (eventlistener.java) to listen for all published events.

package com.Spring.Boot.init.listener;
 
 
import com.Spring.Boot.init.listener.eventModel.StringEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
 
// Event listener
@Component
public class EventListener implements ApplicationListener<StringEvent> {
 
    @Override
    public void onApplicationEvent(StringEvent o) {
        System.out.println("Listen to event, content:"+o.getStr()); }}Copy the code

Next, run the Spring project and look at the printed results. At this point, the event publishing and listening are complete;

6.8 MessageSourceAware. SetMessageSource ()

Internationalize message notification operations

6.9 ApplicationContextAware. SetApplicationContext ()

ApplicationContextAware is used to get the ApplicationContext globally. ApplicationContext is the container, To do this, we can implement the ApplicationContextAware interface to get the ApplicationContext container object; We can make it a public static class so we can grab it anywhere we want,

package com.Spring.Boot.init.aware;
 
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
 
@Component
public class ExtApplicationContextAware implements ApplicationContextAware {
 
    / * * * the Spring container will be loaded after the Spring container calls ApplicationContextAware. * ApplicationContextAware setApplicationContext method are mainly used for global access ApplicationContext context, */
 
    private static ApplicationContext applicationContext;
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (ExtApplicationContextAware.applicationContext == null) {
            ExtApplicationContextAware.applicationContext = applicationContext;
        }
        System.out.println("========ApplicationContext configured successfully ========");
        System.out.println("= = = = = = = = in ordinary classes by calling the SpringBootBeanUtil. GetApplicationContext retrieved applicationContext objects () = = = = = = = =");
        System.out.println("========applicationContext="+ ExtApplicationContextAware.applicationContext +"= = = = = = = =");
    }
 
    /** * get applicationContext *@return* /
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
 
    /** * Get Bean. * by name@param name
     * @return* /
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
 
    /** * get Bean. * from class@param clazz
     * @return* /
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }
 
    /** * returns the specified Bean * by name and Clazz@param name
     * @param clazz
     * @return* /
    public static <T> T getBean(String name, Class<T> clazz) {
        returngetApplicationContext().getBean(name, clazz); }}Copy the code

Of course, it can also be injected directly, like this:

    @Autowired
    private ApplicationContext applicationContext;
Copy the code

6.10 ServletContextAware. SetServletContext ()

The servletContext, which is the context of the servlet, is obtained by implementing the ServletContextAware interface;

What is ServletContext: When the WEB container is started, it creates a corresponding ServletContext object for each WEB application, which represents the current WEB application. ServletConfig object maintains the ServletContext object references, developers to write servlet, can through the ServletConfig. GetServletContext method to obtain the ServletContext object.

Because all servlets in a WEB application share the same ServletContext object, Servlet objects can communicate with each other using the ServletContext object. A ServletContext object is also commonly referred to as a Context domain object.

6.11 LoadTimeWeaverAware. SetLoadTimeWeaver ()

LTW is an implementation of AOP. This method is used to retrieve objects woven into AOP using the following weaving method: Classload-time weaving. Most AOP is run-time weaving, where the aspect methods are woven at run time, whereas LTW is woven before class loading. The weaving method is only called when the class file is loaded by the JVM using @enableloadtimeWeaving or a Bean implemented by LoadTimeWeaver, which is also called later in the order;

6.12 ImportAware. SetImportMetadata ()

Another unprinted ImportAware interface is the ImportAware interface, whose methods are called only by the other configuration class @import (xx.class), which is first in order for all @beans in xx.class.

7. Pre-initialization

Method name: BeanPostProcessor postProcessBeforeInitialization ()

Methods executed before each Bean is initialized (how many beans are called and how many times)

Note: With this method enabled, methods annotated with the @postConstruct annotation will become invalid

8. Initialize postposition

Method name: BeanPostProcessor postProcessAfterInitialization ()

Methods executed after each Bean is initialized (how many beans are called and how many times)

The implementation code for pre-initialization and post-initialization is as follows

package com.Spring.Boot.init;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
 
@Component
public class ExtBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // The method executed before each Bean is initialized (how many beans are called and how many times)
        // Note: with this method enabled, methods annotated with the @postconstruct annotation will become invalid
        System.out.println("Initialization pre-method");
        return null;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, StringThrows BeansException {method executed after each Bean is initialized (how many times the Bean is called) system.out.println ("Initialize post-method");
        return null; }}Copy the code

9. Execute the initialization method

There are three initialization methods, namely adding @PostConstruct annotation method, implementing InitializingBean interface, adding initMethod property on @Bean annotation; Let’s go through them one by one

Init method 1: @postconstruct

This is done by adding an @postconstruct annotation to the bean object. Methods decorated with @postconstruct are run after the constructor and before the init() method. If there are more than one, it will execute multiple times.

Note: if the spring implements the BeanPostProcessor interface postProcessBeforeInitialization () method, which is 12 initial rear method, and then @ PostConstruct annotation will be failure;

Code sample

package com.Spring.Boot.init;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
 
/ / @ PostConstruct annotation
@Component
public class ExtPostConstruct {
 
    / * * *@PostConstructThe modified method is run after the constructor and before the init() method. If there are multiple will perform multiple * note: if the spring implements the BeanPostProcessor interface postProcessBeforeInitialization method of it@PostConstructComments are invalid */
    @PostConstruct
    public void init() {
        System.out.println("First init...");
    }
 
    // Execute multiple times
    @PostConstruct
    public void init1() {
        System.out.println("Second init1..."); }}Copy the code

11, InitializingBean. AfterPropertiesSet ()

One of spring’s initialization methods, which performs custom initialization behavior after the BeanFactory has finished setting its properties.

Order of execution: execute before initMethod and after @postconstruct

Code sample

package com.Spring.Boot.init; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; @Component public class ExtInitializingBean implements InitializingBean { @Override public void afterPropertiesSet() Throws Exception {// An InitializingBean executes once // The Spring initialization method executes custom initialization behavior after the BeanFactory has completed the property setting. Execute before initMethod and after @postConstruct system.out.println ("InitializingBean"); }}Copy the code

12, the init method

The bean configuration file property init-method is used to specify the execution method when the bean is initialized, instead of inheriting the InitializingBean interface,

Note that the initialization method cannot be used until a complete instance of the class has been created.

In the sample code, define a class: BeanTest. Java, and define an initialization method initMethod_1() in the class.

package com.Spring.Boot.init.bean;
 
public class BeanTest {
    
    // The initialization method to be performed
    public void initMethod_1(){
        System.out.println("I'm beanTest's init method."); }}Copy the code

XML configuration mode

Annotation configuration mode

package com.Spring.Boot.init;
import com.Spring.Boot.init.bean.BeanTest;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component()
public class InitMethod  {
    
    // Add the initMethod property to the @bean annotation to point to the initMethod_1 initialization method in the class
    @Bean(initMethod = "initMethod_1")
    public BeanTest getBeanTest(){
        return newBeanTest(); }}Copy the code

13. In use

At this point, the bean object is fully created, is a complete object, and is being used by other objects;

14. Destruction process

It should be noted here that beans managed by the Spring container are singletons by default, with an @scope annotation on top of the class, and so on

package com.Spring.Boot.init;
 
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
 
@Component()
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
// @scope (value = "singleton"
public class InitMethod  {
 
  // methods....
 
}
Copy the code

To set it to multiple instances, you just need to change the @scope attribute value. Just like this, the multiple instances pattern is also called the prototype pattern. Instead of recreating a bean object, it is implemented using the deep-copy technique, that is, copying an object for use

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
// @scope (value = "prototype"
Copy the code

Why singletons and multicases? Because, well, where the destruction process goes depends on whether you’re singleton or multiple;

In singleton mode, you will execute the DisposableBean.destroy() Method, and then destroy-method;

14.1 DisposableBean. Destroy ()

Singleton mode of destruction, sample code

package com.Spring.Boot.init.destroy;
 
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;
 
/** * Destruction method */
@Component
public class ExtDisposableBean implements DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("I was destroyed."); }}Copy the code

When the main method ends, the console prints the following result

14.2 destory – method method

Again, take the case of process 11, except this time we will add the @bean attribute to destroyMethod, pointing to the destroyMethod_1() method.

package com.Spring.Boot.init;
 
import com.Spring.Boot.init.bean.BeanTest;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
 
@Component()
public class InitMethod  {
 
    // Add the initMethod property to the @bean annotation to point to the initMethod_1 initialization method in the class
    // Add the destroyMethod attribute on the @bean annotation to point to destroyMethod_1 in the class to execute the destruction method
    @Bean(initMethod = "initMethod_1",destroyMethod = "destroyMethod_1")
    public BeanTest getBeanTest(){
        return new BeanTest();
    }
}
BeanTest.java

package com.Spring.Boot.init.bean;
 
public class BeanTest {
 
    // The initialization method to be performed
    public void initMethod_1(){
        System.out.println("I'm beanTest's init method.");
    }
 
    // The destruction method to be performed
    public void destroyMethod_1(){
        System.out.println("I'm beanTest's init method."); }}Copy the code

XML configuration

<bean id="beanTest" class="com.BeanTest" destroy-method="destroyMethod_1"></bean>

15. Return the bean to the user, who controls the rest of the life cycle

Since Spring cannot manage the bean objects in multi-case mode, the life cycle is in the hands of the user. After the user runs out of bean objects, the Java garbage processor will automatically recycle the useless objects.

conclusion

Spring IOC and the full life cycle are over here. If you understand and understand the process, you will be able to do well in the interview process and get a high salary offer. If you think a blogger wrote something useful to you, please give it a thumbs up! If you don’t understand anything, feel free to leave a comment in the comments section!

Original link: blog.csdn.net/qq_27184497…