Java framework learning (3) spring5 advanced 49 lectures

Article Directory

1、BeanFactory与ApplicationContext

The BeanFactory is responsible for:

  • Create, manage and configure objects (Bean) in the application
  • Implement IoC (Inversion of Control) and DI (Dependency Injection)
  • It is the core mechanism of spring.

ApplicationContext is a subinterface of BeanFactory. Compared with BeanFactory, ApplicationContext combines four other interface functions, so that it can support:

  • Internationalization (MessageSource, multilingual support)
  • Resource resolution loading (ResourcePatternResolver, load resources according to wildcard matching resource names)
  • Obtain environment configuration information (EnvironmentCapable, load different configuration files according to the configured environment parameters, so as to achieve flexible configuration and adaptation in different environments.)
  • The event publishing function (ApplicationEventPublisher, allows the Bean in the application to send events. At the same time, other Beans can listen to these events, 使用@EventListener注解and take corresponding measures when the event occurs. This facilitates the decoupling of the application and the communication between modules Mechanisms).

insert image description here

insert image description here

2. Container implementation of BeanFactory and ApplicationContext

Container implementation of BeanFactory

1. Create the implementation class object of BeanFactory.
2. Define bean (type, scope, etc.), and register to BeanFactory
3. Register commonly used post-processors. (parsing annotations, injecting, etc.)

insert image description here
insert image description here

Things BeanFactory won't do:

  • Will not actively add Bean post-processors
  • Will not actively call the Bean's post-processor to parse the annotation
  • Will not actively initialize the singleton
  • won't parse $with#

It can be seen that BeanFactory implements the basic functions of the container, and the container implementation of ApplicationContext to be discussed below will implement the above functions one by one.

Post Processor Sort

There are many Bean post-processors, which are used to parse different annotations, such as @Autowired, @Resourceetc. The processor has its fixed execution order, and of course it can also be changed by adding a comparator.

@AutowiredWhen they appear at @Resourcethe same time, the execution result is related to the execution order of the Bean post-processor.
insert image description here

Container implementation of ApplicationContext

The ApplicationContext in Spring is an advanced container for managing beans, and it provides a variety of implementations to suit different scenarios and requirements. The four common implementation methods are:

1. ClassPathXmlApplicationContext: Load and manage beans through the XML configuration file under the classpath.

2. FileSystemXmlApplicationContext: Load XML configuration files through the file system path to manage beans.

3. AnnotationConfigApplicationContext: Based on the implementation of Java annotations, use @Configuration and @Bean annotations to configure beans.

4. WebApplicationContext: used for Web applications, loading Web-related configuration information.

1 and 2 are based on XML file configuration to build container content, 1 is to read by loading XML file resources, and 2 is to read directly from the XML file path.

3 and 4 are based on @Configuration and @Bean annotation configuration. The difference is that the fourth method integrates TomcatServer and configures beans related to web page request processing, mainly including: ServletWebServerFactory, Servlet distribution, Servlet request distribution registration, and corresponding The controller bean for the request path.
insert image description here

3. Bean life cycle

The main life cycle of Bean includes:

  • 1. Instantiation.
  • 2. Dependency injection: @Autowired
  • 3. Initialization: @PostConstruct
  • 4. Destroy: @PreDestroy

insert image description here

Bean Post Processor

In addition to the basic four life cycles, you can also target more refined life cycle stages by adding Bean post-processors to enhance functions, such as:

  • Before instantiation execution, after instantiation execution
  • Before dependency injection (@Autowired, @Resource, @Value)
  • before initialization, after initialization
  • before destroying

insert image description here
insert image description here

4. Common Bean post-processors

  • 1. Common annotation post processor: parse @Resourse, @PostConstruct, @PreDestroy
  • 2. autowired annotation processor: parsing @Autowired, @Value

insert image description here
From the above results, we can see that the execution priority of the common post-processor is higher.

  • ConfigurationPropertiesBindingPostProcessor:解析@ConfigurationProperties

insert image description here

5. Common BeanFactory post-processors

  • ConfigurationClassPostProcessor: The main responsibility is to parse the @Configuration annotated class, identify the @Bean method in it, and also parse @ComponentScan, @Import, @ImportResource
  • MapperScannerConfigurer: Parse @Mapper, corresponding to the MapperScan annotation of mybatis.

6. Aware and InitializingBean interfaces

Aware interfaces are a set of special interfaces that allow a Bean to perceive or obtain certain aspects or context information of a container. By implementing the Aware interface, the Bean can interact with the Spring container and obtain some useful information or perform specific operations.
insert image description here
Bean initialization logic can be implemented using the InitializingBean interface.

The functions implemented by the Aware and InitializingBean interfaces can also be implemented by using the Bean post-processor, but Aware and InitializingBean are built-in interface functions that do not depend on the outside, and are a cohesive usage method, while the post-processing method is decoupled by modules If other modules fail, the execution of the postprocessor may also fail.

7. Callbacks in the initialization and destruction phases

There are 3 ways to specify initialization:

  • 1. @PostConstruct through the post-processor
  • 2. Through the built-in interface of InitializingBean
  • 3. By specifying parameters when annotating @Bean
    insert image description here
    insert image description here

Execution priority:
insert image description here

There are three methods of destruction similar to initialization:
insert image description here

8. The scope of the bean

Spring provides the following common bean scopes:

  • Singleton (single case): During the entire application life cycle, only one Bean instance is created. Each time the bean is requested, the same instance is returned. This is Spring's default scope.
  • Prototype (prototype): Every time the bean is requested, a new bean instance will be created. That is, every time the Bean is obtained, a brand new instance is returned.
  • Request (request): Each HTTP request will create a new Bean instance, suitable for Web applications.
  • Session (Session): Each user session (Session) creates a new Bean instance, suitable for Web applications.
  • Application (application): During the life cycle of the entire Web application, only one Bean instance is created, which is suitable for Web applications.
  • WebSocket (Web Socket): During the lifetime of a WebSocket session, a new Bean instance is created each time.

scope failure

1. A bean whose scope is a singleton, if you want to inject a bean object of other scope (non-singleton), then this non-singleton scope will be invalid.

Experiment: In the e of the singleton, there is a member f, injected, and f is a scope of multiple instances. The final result is that the f obtained in e is not multiple instances, but the same one.

insert image description here
insert image description here

insert image description here

The reason is:
for a singleton object, dependency injection occurs only once, and there are no multiple instances of F that will be used later, so E always uses the F of the first dependency injection.

insert image description here
Solution 1: Use the @Lazy annotation to add to the object to be injected. This annotation will create f through the proxy method of f only when the object is used, so that the called f is multiple instances.

Solution 2: You can set the proxy mode by specifying parameters in the scope annotations of multiple instances of objects.

insert image description here
Solution 3: Inject the factory of F, in the acquisition method, use the factory to build, and then return
insert image description here
Solution 4: Inject the container object, in the acquisition method, use the container to construct the object.

9. Realize AOP based on AJC compiler

AJC (AspectJ Compiler) is the abbreviation of AspectJ Compiler. AspectJ is an extension of the Java language, which is an implementation of AOP (Aspect-Oriented Programming). AspectJ allows developers to directly define aspects (Aspects) in Java code, so as to realize the functions of cross-cutting concerns, such as logging, performance monitoring, transaction management, etc.

AJC的实现需要在Maven中引入AJC编译器插件

The AJC compiler will directly write the content added by @Aspect into the target class.

Classes to be enhanced:
insert image description here
aspect:
insert image description here
After compilation, in the generated target, we can see that our directory class has been rewritten, and the enhanced aspect content has been written into the target class:
insert image description here

The AOP implemented based on the AJC compiler is different from the proxy-based implementation in the spring container. Therefore, AJC enhancement does not require the use of spring containers, and it can enhance static methods, while the essence of agent-based enhancement is to rewrite methods, and static methods cannot be rewritten.

10. Realize AOP based on agent class loading

Implementing AOP based on agent class loading refers to implementing enhancement based on agent class loading by specifying system operating parameters at runtime.

Experiment:
The aspect points to all methods in the class to be enhanced:
insert image description here
Runtime virtual machine parameter settings:

bashjavaagent:C:\Users\123\.m2\repository/org/aspectj/aspectjweaver/1.9.4/aspectjweaver-1.9.4.jar

AJC implements AOP enhancement in the compilation phase, so the compiled object can be found in the target, and the enhanced target class can be viewed through decompilation.

Based on the enhancement implemented by agent class loading, the enhanced target runs in the JVM.
You can use Ali's Arthas tool to debug the running program:
insert image description here

Through the jad command, specify the target class to be enhanced:
insert image description here
then you can see the enhanced content of class loading.
insert image description here

11. Realize AOP based on JDK dynamic proxy/CGLIB dynamic proxy

JDK dynamic proxy: For the target object that implements the interface, Spring uses JDK dynamic proxy to create the proxy object. JDK dynamic proxy is implemented through Java's native java.lang.reflect.Proxy class. The proxy object implements the target interface, and adds enhanced logic in the invoke method of InvocationHandler, that is, based on reflection,method.invoke('待增强对象', '方法参数');

JDK dynamic proxy can only target interface proxy!

insert image description here

Note: The proxy object has no source code, it is a dynamically generated bytecode during runtime, so the proxy object needs to pass a loader to load the bytecode to the proxy object.
insert image description here

CGLIB dynamic proxy: For target objects that do not implement the interface, Spring uses CGLIB dynamic proxy to create proxy objects. CGLIB (Code Generation Library) is a code generation library that implements proxies by generating subclasses of target classes. The proxy object inherits the target class and adds enhancement logic in its subclass.

The core logic is based on the method in the Code Generation Library
Enhancer.create()to generate a proxy class as a subclass of the target class to be enhanced.

So cglib dynamic proxy can only proxy for inheritable objects to be enhanced!
insert image description here

There are three ways for cglib dynamic proxy to call methods:
1. Through method reflection, method.invoke(target, args)
2. Through method proxy object, pass in target object call, non-reflection, target is required
3. Through method proxy object , incoming proxy object call, non-reflection, requires proxy. The proxy passed in here is FastClassProxy

12. JDK dynamic proxy implementation principle

JDK dynamic proxy is implemented based on reflection.

  • 1. The proxy object must implement the InvocationHandler interface. JDK inherits the Proxy class when implementing it, provides the construction method of InvocationHandler, and passes super to InvocationHandler during execution.
  • 2. Use Proxy.newProxyInstance to generate a proxy object. The proxy object is a dynamically generated bytecode based on ASM (bytecode manipulation framework) technology, so it needs to be passed to the class loader to load the bytecode into an object.
  • 3. The acquisition of the interface method is obtained through reflection, that is, calling the getMethod method from the bytecode of the class. In order to avoid the overhead of multiple call getMethod, the proxy object uses static members to save the method, and through the static code The block is initialized with a value.
  • 4. In order to handle methods with return values, the return value in the proxy object is an Object object. The capture and processing of exceptions in the method are divided into runtime exceptions and checked exceptions. Runtime exceptions are thrown directly, and checked exceptions are wrapped as UndeclaredThrowableException and then thrown.
  • 5. jdk reflection optimization, when the interface method is enhanced, the reflection method is used to call the method, so the performance is lossy, and jdk internally optimizes this. When the number of calls reaches the 17th time, jdk will generate an internal The proxy object of the method, directly call the method of the proxy object instead of calling in the form of reflection.

13. CGLib dynamic proxy implementation principle

What the JDK dynamic proxy enhances is the target class that implements the interface, which is essentially based on reflection.
CGLib dynamic proxy adopts the method of inheritance + method interceptor to enhance the inheritable target class.

1. Generate proxy class: When the target class needs to be proxied, CGLIB will generate a proxy class at runtime, which inherits from the target class and becomes a subclass of the target class.

2. Interceptor: In CGLIB, the logic of the proxy is implemented by an interceptor (MethodInterceptor), which is responsible for executing additional logic before and after the method call of the proxy class. The interceptor is similar to the InvocationHandler in the JDK dynamic proxy.

3. Redirection of method calls: When the method of the proxy class is called, CGLIB will redirect the method call to the intercept() method of the interceptor. In the intercept() method, the enhanced logic to the target method can be implemented and the target method can be called.

4. Proxy object creation: Through the bytecode generation technology, CGLIB converts the definition of the proxy class into bytecode, and uses ClassLoader to load the bytecode, and finally generates the proxy object.

14、MethodProxy

The target method call based on MethodProxy in cglib is a direct call instead of reflection, which makes its performance better than that of JDK dynamic proxy.

In the CGLIB source code, the main implementation of the MethodProxy class is completed by the cooperation of the FastClass class and the MethodInfo class. The following briefly explains the implementation principle of MethodProxy:

1. FastClass: FastClass is a key class in CGLIB, which is responsible for quickly calling a method of a class without calling through the Method object like reflection. FastClass directly calls the method through the index number of the method, thus improving the efficiency of the call. FastClass generates a class that calls methods quickly at runtime through the ASM library.

2. MethodInfo: MethodInfo is used to represent a method in the target class. It contains information such as the name of the method, access modifiers, return type, and parameter types.

3. MethodProxy: In the process of generating proxy classes, CGLIB will generate a corresponding MethodProxy object for each target method. MethodProxy contains information such as the index number and method signature of the target method.

4. When the method of the proxy class is called, the proxy object will call the target method through the invoke(Object obj, Object[] args) method of MethodProxy. The invoke() method internally uses FastClass to quickly call the target method without using Java reflection. Through the invoke(int methodIndex, Object obj, Object[] args) method of FastClass, the target method is directly invoked according to the index number of the target method.

In this way, CGLIB avoids the performance overhead brought by Java reflection and realizes high-performance dynamic proxy. MethodProxy is an important part of this mechanism, which enables CGLIB dynamic proxy to have higher efficiency and performance when proxying classes that do not implement interfaces.

The implementation difference between CGLIB and JDK dynamic proxy

CGLIB and JDK dynamic proxy are two different dynamic proxy implementations, and they have some differences in principle, applicable scenarios and performance. Let's explain the difference between them:

  • Principle and implementation method:

    • JDK dynamic proxy: JDK dynamic proxy is implemented through Java's native java.lang.reflect.Proxy class and InvocationHandler interface. At runtime, the JDK dynamic proxy generates the proxy object of the target interface, and implements the interception and enhancement of the target method through the invoke() method of InvocationHandler.
    • CGLIB dynamic proxy: CGLIB dynamic proxy uses the CGLIB library and bytecode generation technology to generate a subclass of the target class as a proxy class at runtime. In the subclass, CGLIB realizes the interception and enhancement of the target method by generating the MethodProxy object.
  • Proxy type:

    • JDK dynamic proxy: JDK dynamic proxy can only proxy the target class that implements the interface. If the target class does not implement any interface, it cannot be proxied using JDK dynamic proxy.
    • CGLIB dynamic proxy: CGLIB dynamic proxy can proxy the target class that does not implement the interface. It implements the proxy by generating subclasses of the target class, so it can also proxy for classes without interfaces.
  • performance:

    • JDK dynamic proxy: When JDK dynamic proxy calls the proxy method, it involves reflection calls, which has a certain performance overhead. The proxy efficiency is relatively low, especially when there are many proxy methods, the performance drop is more obvious.
    • CGLIB dynamic proxy: When CGLIB dynamic proxy calls the proxy method, it directly calls the method of the generated subclass without reflection call, so it has higher performance than JDK dynamic proxy. It is especially suitable for situations where there are many proxy methods or proxy objects are created frequently.
  • Dependencies and Compatibility:

    • JDK dynamic proxy: JDK dynamic proxy relies on Java's native java.lang.reflect.Proxy class, which has good compatibility with the Java platform and does not need to introduce additional third-party libraries.
    • CGLIB dynamic proxy: CGLIB dynamic proxy depends on the CGLIB library, and the corresponding dependencies need to be introduced when using it. CGLIB dynamic proxies work well on the Java platform, but there may be compatibility issues on other Java virtual machines (JVMs).

15. Spring AOP and selection proxy

AOP (Aspect Oriented Programming, Aspect-Oriented Programming) is actually method-oriented programming, which can be an enhancement of the original method or an adaptation of the original method.

For example, it is necessary to count the execution time analysis of a certain method:
insert image description here

AOP core concept

  • Connection point: JoinPoint, a method that can be controlled by AOP (implies relevant information when the method is executed)
  • Notification: Advice, which refers to the repeated logic, that is, the common function (finally embodied as a method)
  • Pointcut expression: PointCut, which matches the condition of the join point, and the advice will only be applied when the pointcut method is executed. Usually pointcut expressions are used to match the cut-in method.
  • Aspect: Aspect, describing the corresponding relationship between notification and entry point (notification + entry point)
  • Single notification aspect: Advisor, a finer-grained aspect, contains only one notification and pointcut aspect.
  • Target object: Target, the object to which the notification applies.

insert image description here

Advice type

  • Before Advice (Before Advice): Advice executed before the execution of the target method. It is used to do some preprocessing operations before the target method is executed.

  • After Advice: Advice that is executed after the execution of the target method. Post advice executes regardless of whether the target method executes successfully or not.

  • After Returning Advice: Advice executed after the target method executes successfully and returns a result. Can access the return value of the target method.

  • After Throwing Advice: Advice executed after the target method throws an exception. Used to handle exceptions.

  • Around advice (Around Advice): Advice that can be executed before and after the execution of the target method. It can completely control the execution of the target method, including whether to execute the target method and where to execute the target method.

Note: @Around advice differs from other types of advice:

  • @Around notification needs to call ProceedingJoinPoint.proceed() to let the original method execute. If the original method has a return value, it needs to be assigned to the Object object, while other notification types do not need to process the original method.
  • The join point type of @Around advice is ProceedingJoinPoint, while the join point type of other advice is JoinPoint, which is the parent class of ProceedingJoinPoint.

@Order controls the notification order

When the pointcuts of multiple aspects match the target method, multiple advices will be executed. So what is the order of execution?

  • 1. Among different aspect classes, the default is to sort alphabetically by the name of the aspect class
    • Notification before the target method: execute first in alphabetical order
    • Notification after the target method: alphabetically sorted last and executed first
  • 2. You can add the @order (number) annotation to the aspect class to execute the priority
    • Notification before the target method: the one with the smaller number is executed first
    • Notification after the target method: the one with the larger number is executed first

Sequence control can only be based on the aspect class, and the specific notification method in the class cannot control the sequence.

insert image description here

Pointcut expressions (Pointcut) and @PointCut

Use the pointcut expression to match the cut-in method. The matching methods are:

  • execution(...): match according to the return value of the method, package name, class name, method name, method parameters and other information, use execution
  • @annotation(...): match according to the annotation
    insert image description here

Pointcut expressions can be extracted by annotation @Pointcut. Then reuse where needed:
insert image description here

Join Points

A join point is an input parameter of an enhanced method, which is used to obtain information about the actual running method.
insert image description here
insert image description here

AOP based on code implementation

Four steps are required:

  • 1. Prepare the cutting point
  • 2. Prepare the notice
  • 3. Prepare the cutting surface (cutting point + notification)
  • 4. Create an agent

insert image description here
insert image description here

Spring's selection rules for proxies

The Spring framework will automatically select the appropriate proxy method according to the characteristics of the target bean. This choice is transparent, and developers do not need to explicitly specify which proxy method to use. When Spring AOP is configured, if the target bean implements the interface, Spring will use the JDK dynamic proxy; if the target bean does not implement the interface, Spring will use the CGLIB proxy.

For the above experiment, use ProxyFactorythe created proxy object:

  • If proxyTargetClass = false is set and the target implements the interface, implement it with jdk.
  • If proxyTargetClass = false is set and the target does not implement the interface, the cglib implementation is used.
  • If proxyTargetClass = true is set, the cglib implementation is always used.

16. Pointcut matching

Use the pointcut expression to match the cut-in method. The matching methods are:

  • execution(...): match according to the return value of the method, package name, class name, method name, method parameters and other information, use execution
  • @annotation(...): match according to the annotation

insert image description here

17. From @Aspect to @Advisor

Aspect is an advanced aspect, which is relatively simple to implement, and can be annotated:
insert image description here

Advisor is a low-level aspect that is often used inside the framework implementation. Creating an Adivisor requires a pointcut + advice (created by MethodInterceptor)

insert image description here

During the Spring startup process, all aspects will be parsed. If it is a high-level aspect Aspect, it will be converted to a low-level aspect Adviser.
insert image description here

18. Execution of notice

Convert all notifications to surround notifications based on the adapter pattern

No matter which method (JDK or CGLib) the ProxyFactory creates the proxy on, the last call to the Advice notification is a MethodInvocation object, and the non-surrounding advice will be uniformly converted to the surrounding advice before execution.

insert image description here
insert image description here

Realize the execution of notifications based on the chain of responsibility model

insert image description here

19. Dynamic notification call

  • Static notification call: no parameter binding
  • Dynamic notification call: parameter binding is required

insert image description here

41. Spring automatic configuration principle

@Import three-party configuration introduction

Sometimes we need to make some configuration class beans for three-party dependencies. In order to facilitate the reuse of other projects, we usually write them in a configuration class. When using this configuration class in this project, we can import it through the @Import annotation To the configuration class of this project:

insert image description here

In the above writing, if there are too many three-party configuration classes, there will be many @Import annotation parameters. You can build an ImportSelect, and put the three-party configuration class information into the ImportSelect class:

insert image description here
Furthermore, to avoid listing configuration class information in the Java code, you can directly list the configuration information in the configuration file, and then import it. This configuration file is generally
insert image description here
in the .factories file in the META_INF directory under the resource directory: then In ImportSelector, you only need to use SpringFactoriesLoader to load and convert to a list of string types:
insert image description here

Bean name conflict:
If the bean configured by the three parties is the same as the bean configured in this project during configuration, the bean configured later will overwrite the bean configured earlier.

If you don't want to be overwritten, you can setAllowBeanDefinitionOverridingset it to false:
insert image description here
so how to ensure the import order of the configuration?
You can change the ImportSelector interface to the DeferredImportSelector interface, that is, delay the configuration of the three parties, and give priority to ensuring that the configuration of this project is executed first:
insert image description here
then in the three-party configuration class:
use the @ConditionOnMissingBean annotation and use it only when the Bean is missing:
insert image description here

The principle of automatic configuration when SpringBoot starts

When Spring starts, there is an annotation @SpringBootApplication, which can be seen as a collection of three annotations:

  • @Configuration : Allows to register additional beans or import other configuration classes in the context
  • @ComponentScan : Scans beans annotated by @Component ( @Service , @Controller
    ). By default, the annotation scans all classes under the package where the class is located.
  • EnableAutoConfiguration: Enable SpringBoot's automatic configuration mechanism, which is annotated by:
    • @AutoConfigurationPackage: An annotation used to specify the scanning scope of the automatic configuration class, which is usually placed on the startup class to set the basic package path of the automatic configuration.
    • The @ Import annotation is used to import the configuration class or Bean into the current class. The Import annotation in EnableAutoConfiguration will import the automatic configuration import selector, AutoConfigurationImportSelector, and this import selector will configure META-INF / spring.factories in Resource All auto-configuration beans are added to the Spring container.

insert image description here
Summarize:

  • 1、Spring启动类会加@SpringBootApplication注解,该注解可以看作是三个主要的注解@Configuration,@ComponentScan和@EnableAutoConfiguration的集合。
  • 2、@Configuration声明了启动类为主配置类,@ComponentScan则会扫描主配置类及其所在包下所有类,将@Component注解标识的类或@Component的复合注解,如@Service、@Controller、@Repository等加入到Spring容器。
  • 3、重点是@EnableAutoConfiguration注解,它可以看作是@AutoConfigurationPackage和@Import注解的集合,@AutoConfigurationPackage 作用是告诉Spring Boot 自动配置类的扫描范围,默认会限定在主类所在的包及其子包中搜索自动配置类。@Import注解中导入的AutoConfigurationImportSelector则会调用SpringFactoryLoader将META-INF目录下spring.factory文件中声明的Bean都加入到Spring容器中。

Custom automatic configuration import Spring

47. @Autowired Bottom

@Autowired is injected by type, and the underlying implementation is more complicated.

48. Event listener

Event publishing and processing process

Step 1: Build an event object, inherited from ApplicationEvent
Step 2: Send events through the time publisher:

insert image description here
Step 3: The event listener implements the listener interface, that is, ApplicationListener, which needs to provide an event type as a generic instantiation. Then rewrite the onApplicationEvent() method of the interface to implement event processing logic.

insert image description here

The event listener can also notify the @EventListener annotation to directly load the listener’s method of handling the listening event to implement monitoring. Note that just like the event type needs to be passed in the interface, the listening processing method needs to pass in the event object:
insert image description here

Use thread pool to process events asynchronously

The publisher event is published at the bottom by calling a SimpleApplicationEventMuticaster to broadcast notification events. The thread pool is not used by default, but we can make the execution of events asynchronous by setting the thread pool object taskExecutor.
insert image description here
insert image description here
Through the @Bean annotation, the thread pool object is constructed, and the Spring container will execute the method and return the thread pool object to us when we need this object.
insert image description here

Implementation principle of custom annotation simulation @EventListener

insert image description here

49. Custom event dispatcher simulates event publishing

Step 1: Create an abstract method to implement the application event publisher interface ApplicationEventMulticaster
Step 2: Build the event publisher @Bean method, return the event publisher object, first obtain the listener collection from the container, and then need to rewrite the event publisher Two methods: addApplicationListener() is used to collect listeners, and multicastEvent() is used to publish events.

insert image description here
Step 3: In the collect listener method, the event type of the listener needs to be obtained, and then the listener is packaged as a listener GenericApplicationListener that supports event type checking. Only when the event type is consistent with the listening type, the event publishing is executed. It can also be posted to the thread pool here. Finally, listeners that support type checking are added to the listener collection.
Step 4: Since the listener collection has been encapsulated as a listener with event type inspection function, its event type inspection support function supportEventType() can be called to determine whether to execute the listener's event publishing callback.

insert image description here
insert image description here

insert image description here

insert image description here

Guess you like

Origin blog.csdn.net/baiduwaimai/article/details/131975491