Talk about your understanding of Spring

Spring content is very wide, is an open source framework collection, on behalf of the product has spring Framework, Spring Boot, Spring Cloud.

The main functions provided by Spring container are object container management, dependency injection, easier management of application development. The commonly used modules of Spring also include MVC, AOP, transaction module, Web MVC is convenient for web interface development. Aop can realize a common operation encapsulation, such as logging, permission control, custom cache, Custom annotations.

For example, add a few lines of database configuration to the application. Properties file to automatically configure the database. The principle is also based on spring extension development. At some point in spring container initialization (beanFactoryPostProcess) Java’s SPI functionality loads the written configuration classes to handle the automatic configuration process. In general, SpringBoot is an extension of Spring development, which is easier to use.

Spring Cloud provides several modules that make it easier to manage multiple services, namely microservices, based on the efficient construction and development projects of Spring Boot. The main components are spring Cloud Gateway, Config configuration center, Eureka service registry, Feign services see call Framework, Robbin load balancing component, Hystrix fuse degrade component

How to configure beans

xml

@Component based on annotations (@service @controller @Configuration @repository)

@bean annotation method

@ Import annotations

You can import a bean. You can import a class that implements a register that automatically handles the registration logic in the registration method. You can import a class and return multiple arrays of class namesCopy the code

The difference between @Autowired and @Resource

Autowird defaults to automatic injection based on type type, and you can specify the bean name with @qualifier

Resource is automatically injected based on the name by default, and can be injected based on type, annotation inside the configuration

The BeanFactory and ApplicationContext

BeanFactory is a bean factory that manages things like bean creation/retrieval

ApplicationContext inherits beanFactory to implement more functionality and initialization procedures

How many kinds of bean scope does Spring have

  1. The singleton default
  2. Prototype creates a new bean for each fetch
  3. Session Valid within a session
  4. Request Each HTTP request is valid
  5. Global Session ServletContext scope

ApplicationContext initialization process

The core

  1. PrepareBeanFactory (Create the environment, register some default built-in beans, beanProcessor)

  2. The postProcessBeanFactory bean factory postprocessing can be ignored

  3. Implementation of invokeBeanFactoryPostProcessors/call spring beanFactoryPostProcessor method

    Find/instantiate all beanFactoryPostProcessor classes in beanFactory and execute the postProcessBeanFactory method. A class is one of the most important ConfigurationClassPostProcessor, the method to realize it is scanning the classpath, encapsulated into a beanDefinition added to beanDefinitionMap, This is where the import annotation parses the class to be added to the beanDefinition, and this is where the SpringBoot auto configuration takes place, importing a class, using spi, and scanning to add more classes

  4. registerBeanPostProcessors

    Find/instantiate all the beanPostProcessor classes in the beanFactory and order them in priority order to be used during bean creation

  5. Initialization Internationalization component initialization event Dispatcher initialization event Listener ignored

  6. FinishBeanFactoryInitialization instantiation of the rest of the bean

    Get all the beanNames, instantiate them, perform the dependency injection/loop dependency processing, cache, and set of processing methods after the bean is created

  7. The release Finish event was ignored

Spring Bean life cycle

AbstractAutowireCapableBeanFactory.createBean / doCreateBean

The step/createBean method that goes through the bean creation and destruction process

  1. Scan the specified path and add beanDefinitionMap to the bean definition map based on annotations such as @Component

  2. Instantiate the bean and create it through reflection

  3. Set auto-injected properties for the bean (populateBean)

  4. Initialize beans (InitializeBeans)

    1. See if you can inherit the Aware interface and implement the Aware methods, such as setBeanName and setBeanFactory

    2. Perform the rear bean processors postProcessBeforeInitialization method

      Check one ApplicationContextAwareProcessor Aware set ApplicationAware related methods

      One of the InitDestroyAnnotationBeanPostProcessor @ PostConstruct method execution

    3. 1. Check if InitializingBean is InitializingBean and execute afterPropertiesSet. 2. Execute custom initMethod

    4. Perform the rear bean processors postProcessAfterInitialization method

  5. Check to DisposableBeans, so that you can execute the relevant destruction procedures at the time of destruction

  6. Bean in use…

  7. Methods related to destruction

    1. Perform rear bean processors postProcessBeforeDustruction method
    2. Check whether you have implemented DisposableBean to execute the destroy method
    3. Execute custom deStory methods

The issue of when Spring executes the destroy method

Context manually calls the registerShutdownHook method, adding a system shutdownHook that executes the context’s doClose method

RegisterShutdownHook is called manually. For example, Spring Boot calls the registerShutdownHook method after the context’s refresh method is called, adding a container destruction callback

A series of Beanpostprocessors
  • BeanPostProcessor

    • PostProcessBeforeInitialization initializes the front method
    • Rear postProcessAfterInitialization initialization method
  • InstantiationAwareBeanPostProcessor extends BeanPostProcessor

    • PostProcessBeforeInstantiation instantiate the preposition Don’t usually generate object, it is parsing information cache
    • Rear postProcessAfterInstantiation instantiation process
    • Postprocessing of postProcessProperties bean properties (automatic injection)
    • Rear postProcessPropertyValues attribute processing (automatic injection/overdue method, using a)
  • DestructionAwareBeanPostProcessor

    • PostProcessBeforeDestruction destroyed before the front method
  • Rear SmartInstantiationAwareBeanPostProcessor intelligent instantiation processor/very deep a rear processor

    • PredictBeanType Determines the class type of the beanName
    • DetermineCandidateConstructors at the time of instantiation bean returned rear constructor of the processor
    • GetEarlyBeanReference gets the post-processing method for the bean being created
  • Rear MergedBeanDefinitionPostProcessor bean definitions processor

    • PostProcessMergedBeanDefinition instantiated modified rear beanDefinition processor (set parsing @ PostConstruct @autowired @ Value such as annotations)
    • ResetBeanDefinition Removes the beanDefinition post-definition method

Spring Bean security issues

The spring container generates its own singleton beans without any security issues. Synchronized locks are added. Security issues occur when multiple threads use properties in beans. Request access is handled simultaneously in the thread pool, while operating on properties in the Controller, which is the shared memory in the heap, which has thread-safety and visibility issues without locking

Solutions:

  1. Add a ThreadLocal variable to isolate each thread’s variables
  2. Change the scope of the bean to Prototype and generate a new bean each time, one per thread, so there are no security issues

Spring creates bean dependencies

How does Spring solve the problem of loop dependencies

Core: Cache

(populateBean) (populateBean) (populateBean) (populateBean) (populateBean) (populateBean) (populateBean) (populateBean) There is no need to recreate Bean A

The process of getting/creating beans

AbstractBeanFactory.doGetBean()

The getBean entry/simple singleton bean process is the getBean method

  • GetSingleton (beanName) from map or cacheTo obtain
    • SingletonObjects level 1 cache fetch
    • No longer retrieved from earlySingletonObjects secondary cache
    • No more fetched from the singletonFactories level 3 cache
  • If the cache cannot be obtained, the cache is not created or is being created, and the creation process starts
  • DependName () getBean(dependName)
  • GetSingleton (beanName ObjectFactory) callscreatebean
    • Synchronized locks during bean creation
    • Tag in the bean is creating singletonsCurrentlyInCreation. Add (beanName)
    • Objectfactory.getobject () -> createBean() -> doCreateBean actually creates the bean logic
      • CreateBeanInstatnce Instantiates the bean
      • SingletonFactories. Add (beanName, singletonFactory) and add a post-processing getEarlyBeanReference. You can customize the bean when you fetch the cache
      • Automatic injection
      • Initialize/detail the bean creation process
  • AddSingleton (beanName, bean) adds the bean in its final state to the beanMap, removing the second and third caches

Related code screenshot

Lock the bean before creating it

Add the create cache bean

Finally adding beans

Why level 3 caching

Actually l3 cache is the role of the second level cache, because spring wanted us to developers are created in the early access beans when dealing with a rear extension, if there are only two levels of cache, every time is in early is creating bean obtained will perform again processing method, if inside the extension method returns a new object, This will cause the bean to be created differently each time it is fetched early, so it is not a singleton. So spring adds the post-processed beans to the second-level cache after fetching the beans from the third-level cache. Next time the beans are fetched directly from the second-level cache, there is no need to fetch the beans from the third-level cache, and there is no need to perform another post-processing

The core: Basically, make sure that the early post-processing of the bean being created is done only once, that the result is cached, and that the result is fetched directly the next time

Examples of action: The AOP proxy dependency injection application, also known as the three-level cache, is obtained through the three-level cache when the A bean is injected into the B bean during the creation process. The original native instance A bean is wrapped with the proxy after the getEarlyBeanReference postprocessing. Make B injected A boost after objects, otherwise the before postProcessAfterInitialization to initialize A of agent packaging, B can only be injected into A build up in front of the object, it is wrong

Principle of Bean dependency injection Setting properties (populateBean)

Autowired Automatic bean injection process

Core classes: AutowiredAnnotationBeanPostProcessor

The entrance AbstractAutowireCapableBeanFActory populateBean method

  • AutowiredAnnotationBeanPostProcessor.postProcessProperties()

    • FindAutowiringMetadata finds the @autowired /@Value attribute metadata

    • AutowiredFieldElement.inject()

      • The beanFactory. ResolveDependency find need to inject the value

        Find the bean based on Type

        doResolveDependency -> descriptor.resolveCandidate

      • Injected into the field by reflection

Design patterns used by Spring

  1. Singleton pattern: Beans in context are singleton by default
  2. Factory pattern: Create bean objects through the beanFactory factory
  3. Proxy pattern: AOP implementations are based on dynamic proxies
  4. Template mode: jdbcTemplate, redisTemplate uses template mode
  5. Observer mode: The time observer mode used by spring’s event mechanism, listener
  6. Adapter pattern: Spring MVC, handlerAdapter, find the corresponding handling method according to the handler, which uses suport/handle mode
  7. Decorator pattern: Wrapper decorator

Spring MVC process

  1. The request goes first to the servlet’s Service method

  2. Spring’s DispatcherServlet inherits the Servlet class, implements the Service method, and handles MVC logic in the doDispatcher method

  3. Iterating through the handlerMapping component to find the appropriate request handler (the controller’s method)

  4. Walk through the handlerAdapter component to find the appropriate handlerAdapter to handle the handler

    ApplyPreHandler (calls the interceptor’s preHandle method)

  5. The handlerAdapter calls the processing methods in the handler, the actual processing logic of the business (controller)

  6. Return a ModelAndView object (return data and view name or view)

    ApplyPostHandle (call the interceptor post-processing method postHandle)

  7. The result after handling handle

    1. Check whether exceptions exist and handle exceptions (@controlerAdvice @ExceptionHanlder configuration related to annotations)
    2. The viewResolver finds the view based on the viewName in the result modelAndView
    3. The View renders the view to Response based on the model (data) in the resulting modelAndView

    TriggerAfterCompletion triggerAfterCompletion triggerAfterCompletion triggerAfterCompletion

Screenshot of core process code

The way of aop

Aop oriented to aspect programming, is a kind of programming idea, the business irrelevant operations, such as logging, permission control extraction to a place with the same processing, reduce the system repeated code, reduce the coupling degree between modules, improve readability and maintainability

It can be implemented based on dynamic proxies

The dynamic proxy for @Configuration changes the Class of beanDefinition to the class generated by Cglib

If @enableAspectJAutoProxy is used, the generated beanDefnition class is still the original class if the proxy conditions are met, but the created object becomes the proxy object

What is the difference between Spring AOP and AspectJ AOP

Spring AOP is enhanced at run time (bytecode generation), SapectJ AOP is enhanced at compile time (bytecode class generation)

Spring aop principle

@EnableAspectJAutoProxy -> @Import(AspectJAutoProxyRegisterar.class)

Registered a rear AnnotationAwareAspectJAutoProxyCreator processor in it

The core is postProcessAfterInitialization – > wrapIfNecessary

  • GetAdvicesAndAdvisorsForBean (class, beanName) according to the bean’s class to find the right aop advisor

    AbstractAdvisorAutoProxyCreator findEligibleAdvisors

    • AdvisorRetrievalHelper. FindAdvisorBeans find all implementation Advisor bean is generally not to do so, so generally returned empty

    • aspectJAdvisorsBuilder.buildAspectJAdvisors

      • Find the bean annotated with @aspect
      • Parses the Aspect Class content, finds all the advisors, and adds them to the cache
    • FindAdvisorsThatCanApply (Advisors, beanClass) finds advisors that satisfy the Bean class from all advisors

    • Sorting advisors,

  • CreateProxy (Class, beanNmae, Advisors, Bean) actually generates the enhanced bean procedure

    • new ProxyFactory();
    • The factory set up advisors,
    • EvaluateProxyInterfaces determine whether to use the Cglib dynamic proxy based on the proxyTargetClass attribute. If proxyTargetClass=false, JDK dynamic proxies are required to implement the interface
    • Proxyfactory.getproxy () the proxyFactory creates the proxy logic
      • Obtain CglibAopProxy or JdkDynamicAopProxy based on the configuration
      • Cglibaopproxy. getProxy Normal ctglib proxy creation process
        • new Enhancer();
        • Get callbacks according to the advisors
        • enhancer.create()

The bean-compliant advisors are saved to the AdvisedSuport, also known as the ProxyFactory, through which the proxy is created

Spring Boot automatic configuration process

SpringApplication is a container that launches the utility class

SpringApplication.run(class);

  • new SpringApplication(class)

    • Decide on webApplicationType NONE or SERVLET/and see if your classpath has a SERVLET class
    • Load the meta-inf/spring. All ApplicationContextInitializer factorie implementation classes (loadProperties similar spi but not spi)
    • Load all ApplicationListener implementation classes in meta-INF /spring.factorie
  • run(args)

    • Load the meta-inf/spring. All SpringApplicationRunListener factorie implementation class Currently only one EventPublishingRunListener, spring configuration launched several process

    • Listeners mark the start of an application

      • Publish ApplicationStartingEvent The application is starting the event

        LoggingApplicationListener to monitor this event, and to monitor the below environmentPrepared events, configuration slf4j logging

    • PrepareEnvironment Prepares the environment

      • GetOrCreateEnvironment () Creates the environment

      • listeners.environmentPrepared(environment);

        • Release applicationContext ApplicationEnvironmentPreparedEvent events in it

          One ConfigFileApplicationListener listening to this event, and to load all the EnvironmentPostProcessor, to deal with the Enviroment, realize the load configuration to the Enviroment

      • CreateApplicationContext () creates the IoC container, simply instantiating the Context

      • PrepareContext () prepares containers/sets Environment, Listeners, configuration classes, etc

        • Context. SetEnvironment (environment) Sets the environment
        • ApplyInitializers loaded ApplicationContextInitializer before implementation in the initialize method of dealing with the context
        • listeners.contextPrepared() The container is ready to complete the event
          • Release events ApplicationContextInitializedEvent
        • Set the configuration class for applicationContext.
        • listeners.contextLoaded() Container load completion event
          • Set up applicationListeners on applicationContext
          • Publish the ApplicationPreparedEvent event
      • RefreshContext () refreshes the container

        • The refresh container applicationContext. Refresh ()

          In the refresh onRefresh createWebServer, create TomcatWebServer, set to TomcatContext ServletContextInitializer initialization method, start Tomcat, Set ROOT_WEB_APPLICATION properties, perform the custom ServletContextInitializer onStartup method

        • Context. RegisterShutdownHook () registered container closure treatment

      • Listeners have started the application

        • Publish the ApplicationReadyEvent event
      • The application is running

        • Publish the ApplicationReadyEvent event