Comprehensive analysis of high-level core knowledge in Java-commonly used frameworks (what design patterns are used in Spring?)

1. Inversion of Control (IoC) and Dependency Injection (DI)

IoC (Inversion of Control) is a very important concept in Spring. It is not a technology, but a decoupling design idea. Its main purpose is to use the "third party" (IOC container in Spring) to achieve decoupling between dependent objects (IOC is easy to manage objects, you can just use it), thereby reducing the coupling between codes . IOC is a principle, not a pattern. The following patterns (but not limited to) implement the IoC principle.

The Spring IOC container is like a factory. When we need to create an object, we only need to configure the configuration file/annotation, without considering how the object is created. The IOC container is responsible for creating objects, connecting objects together, configuring these objects, and processing the entire life cycle of these objects from creation until they are completely destroyed.

In an actual project, if a Service class has hundreds or even thousands of classes as its bottom layer, we need to instantiate the Service. You may have to figure out the constructors of all the bottom classes of the Service every time, which may cause People are driving crazy. If you use IOC, you only need to configure it, and then reference it where needed, which greatly increases the maintainability of the project and reduces the difficulty of development.

How to understand the control rollover? For example: "Object a depends on object b. When object a needs to use object b, you must create it yourself. But when the system introduces the IOC container, object a and object b are lost before Direct connection. At this time, when object a needs to use object b, we can specify the IOC container to create an object b to inject into object a". The process in which object a obtains dependent object b changes from active behavior to passive behavior, and control is reversed. This is the origin of the name of control reversal.

DI (Dependecy Inject) is a design pattern for realizing inversion of control. Dependency injection is to pass instance variables into an object.

2. Factory design mode

Spring can use the factory pattern BeanFactoryor ApplicationContextcreate a bean object.

Comparison of the two:

  • BeanFactory: Delayed implantation (when using the bean will be injected to a), compared to ApplicationContextwho will take up less memory, programs start faster.
  • ApplicationContext: When the container starts, whether you use it or not, create it all at once bean. BeanFactoryProvides only the most basic dependency injection support, ApplicationContextexpanded BeanFactory, in addition to BeanFactoryfeatures include additional more features, it is generally developers ApplicationContextwill be more.

Three implementation classes of ApplicationContext:

  1. ClassPathXmlApplication : Treat the context file as a classpath resource.
  2. FileSystemXmlApplication : Load the context definition information from the XML file in the file system.
  3. XmlWebApplicationContext : Load the context definition information from the XML file in the Web system.

Example:

import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.FileSystemXmlApplicationContext; 

public class App {
    
     
	public static void main(String[] args) {
    
     
		ApplicationContext context = new FileSystemXmlApplicationContext( "C:/work/IOC Containers/springframework.applicationcontext/src/main/resources/bean-factory- config.xml"); 
		
		HelloApplicationContext obj = (HelloApplicationContext) context.getBean("helloApplicationContext"); 
		obj.getMsg(); 
	} 
}

Three, singleton design pattern

In our system, there are some objects that we actually only need one, such as: thread pool, cache, dialog box, registry, log object, and objects that act as device drivers such as printers and graphics cards. In fact, this type of object can only have one instance. If multiple instances are created, some problems may arise, such as abnormal program behavior, excessive resource usage, or inconsistent results.

The benefits of using the singleton pattern:

  • For frequently used objects, the time spent creating objects can be omitted, which is a considerable system overhead for those heavyweight objects;
  • Since the number of new operations is reduced, the frequency of using system memory will also be reduced, which will reduce GC pressure and shorten GC pause time.

The default scope of beans in Spring is singleton (singleton). In addition to the singleton scope, beans in Spring also have the following scopes:

  • prototype : Each request will create a new bean instance.
  • request : Each HTTP request will generate a new bean, which is only valid in the current HTTP request.
  • session : Every HTTP request will generate a new bean, which is only valid in the current HTTP session.
  • global-session: Global session scope, only meaningful in portlet-based web applications, Spring5 has no more. Portlet is a small Java Web plug-in that can generate fragments of semantic code (for example: HTML). They are based on portlet containers and can handle HTTP requests like servlets. However, unlike servlets, each portlet has a different session

The way Spring implements singleton:

  • xml :<bean id="userService" class="top.snailclimb.UserService" scope="singleton"/>
  • annotation: @Scope(value = "singleton")

Spring by ConcurrentHashMapsingle-mode specific embodiments manner singleton registry. The core code for Spring to implement a singleton is as follows

// 通过 ConcurrentHashMap(线程安全) 实现单例注册表 
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64); 

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    
     
	Assert.notNull(beanName, "'beanName' must not be null"); 
	synchronized (this.singletonObjects) {
    
     
		// 检查缓存中是否存在实例 
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null) {
    
     
			//...省略了很多代码 
			try {
    
    
				singletonObject = singletonFactory.getObject(); 
			}
			//...省略了很多代码 
			// 如果实例对象在不存在,我们注册到单例注册表中。 
			addSingleton(beanName, singletonObject); 
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null); 
	} 
}
//将对象添加到单例注册表 
protected void addSingleton(String beanName, Object singletonObject) {
    
     
	synchronized (this.singletonObjects) {
    
     
		this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); 
		} 
	} 
}

Four, agency design mode

1. The application of proxy mode in AOP

AOP ( Aspect-Oriented Programming: Aspect-Oriented Programming) can encapsulate the logic or responsibilities (such as transaction processing, log management, access control, etc.) that are not related to the business but are called by the business modules, which is convenient to reduce the duplication of the system code and reduce the number of modules The degree of coupling is conducive to future scalability and maintainability.

Spring AOP is based on dynamic proxy . If the object to be proxied implements a certain interface, then Spring AOP will use JDK Proxy to create proxy objects. For objects that do not implement the interface, JDK Proxy cannot be used for proxying. At this time, Spring AOP will use Cglib . At this time, Spring AOP will use Cglib to generate a subclass of the proxy object as a proxy, as shown in the following figure:

Of course, you can also use AspectJ. Spring AOP has integrated AspectJ, and AspectJ should count The above is the most complete AOP framework in the Java ecosystem.

After using AOP, we can abstract some general functions and use them directly where they are needed, which greatly simplifies the amount of code. It is also convenient when we need to add new functions, which also improves system scalability. AOP is used in scenarios such as log function and transaction management.

2.What is the difference between Spring AOP and AspectJ AOP?

Spring AOP is a runtime enhancement, while AspectJ is a compile-time enhancement. Spring AOP is based on proxying, while AspectJ is based on bytecode manipulation ( Bytecode Manipulation).

Spring AOP has been integrated AspectJ, and AspectJit should be considered the most complete AOP framework in the Java ecosystem. AspectJCompared with Spring AOP, it is more powerful, but Spring AOP is relatively simpler.

If we have fewer aspects, there is little difference in performance between the two. However, when there are too many aspects, it is best to choose AspectJ, which is much faster than Spring AOP.

Five, template method

The template method pattern is a behavioral design pattern that defines the skeleton of an algorithm in operation, while delaying some steps to subclasses. The template method allows subclasses to redefine the implementation of certain specific steps of an algorithm without changing the structure of an algorithm.

public abstract class Template {
    
     
	//这是我们的模板方法 
	public final void TemplateMethod(){
    
     
		PrimitiveOperation1(); 
		PrimitiveOperation2(); 
		PrimitiveOperation3(); 
	}
	
	protected void PrimitiveOperation1(){
    
     
		//当前类实现 
	}
	
	//被子类实现的方法 
	protected abstract void PrimitiveOperation2(); 
	protected abstract void PrimitiveOperation3(); 
}
public class TemplateImpl extends Template {
    
     

	@Override 
	public void PrimitiveOperation2() {
    
     
		//当前类实现 
	}
	
	@Override 
	public void PrimitiveOperation3() {
    
     
		//当前类实现 
	} 
}

In Spring jdbcTemplate, hibernateTemplateclasses that end with Template for database operations, they use the template mode. Under normal circumstances, we use inheritance to implement the template mode, but Spring does not use this method, but uses the Callback mode in conjunction with the template method mode, which not only achieves the effect of code reuse, but also increases flexibility .


Reference material: "Comprehensive Analysis of Java Intermediate and Advanced Core Knowledge" is limited to 100 copies. Some people have already obtained it through my previous article!
Seats are limited first come first served! ! ! There are more Java Pdf learning materials waiting for you! ! !
Students who want to get this learning material can click here to get it for free """""""

Six, the observer mode

The observer pattern is an object behavior pattern. It represents a dependency between an object and an object. When an object changes, the objects that the object depends on will also react. The Spring event-driven model is a classic application of the observer pattern. The Spring event-driven model is very useful and can decouple our code in many scenarios. For example, we need to update the product index every time we add a product. At this time, we can use the observer mode to solve this problem.

1. Three roles in the Spring event-driven model

1) Event role

ApplicationEvent( org.springframework.contextRole under the package) to act as an event, this is an abstract class that inherits java.util.EventObjectand implements java.io.Serializablethe interface.

Spring in the presence of the following events by default, they are to ApplicationContextEventachieve (inherited from ApplicationContextEvent):

  • ContextStartedEvent: ApplicationContextEvent triggered after startup;
  • ContextStoppedEvent: ApplicationContextEvent triggered after stopping;
  • ContextRefreshedEvent: ApplicationContextEvent triggered after initialization or refresh;
  • ContextClosedEvent: ApplicationContextEvent triggered after closing.

2) The role of event listener

ApplicationListenerAct as an event listener role, it is an interface, which defines a single onApplicationEvent()method to deal with ApplicationEvent. ApplicationListenerSource interface class as can be seen in the interface definition of the event as long as the interface seen achieve ApplicationEventit. So, as long as we achieve in Spring ApplicationListenerinterface onApplicationEvent()method to complete the listening event

package org.springframework.context; 
import java.util.EventListener; 
@FunctionalInterface 
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
    
     
	void onApplicationEvent(E var1); 
}

3) Role of event publisher

ApplicationEventPublisher Acting as a publisher of events, it is also an interface.

@FunctionalInterface 
public interface ApplicationEventPublisher {
    
     
	default void publishEvent(ApplicationEvent event) {
    
     
		this.publishEvent((Object)event); 
	}
	
	void publishEvent(Object var1); 
}

ApplicationEventPublisherInterface of publishEvent()this method AbstractApplicationContextis implemented in a class, read implement this method, you'll find that it really is an event by ApplicationEventMulticastercoming out of the broadcast. The specific content is too much, so I will not analyze it here, and I may write an article to mention it later.

2. Spring's event flow summary

  1. Define an event: implement an inheritance ApplicationEvent, and write the corresponding constructor;
  2. Define an event listener: Implement ApplicationListenerInterface, rewriting onApplicationEvent()method;
  3. Use the event publisher announced: by ApplicationEventPublisherthe publishEvent()way to publish news.

Example:

// 定义一个事件,继承自ApplicationEvent并且写相应的构造函数 
public class DemoEvent extends ApplicationEvent{
    
     
	private static final long serialVersionUID = 1L;
	 
	private String message; 
	
	public DemoEvent(Object source,String message){
    
     
		super(source); 
		this.message = message; 
	}
	
	public String getMessage() {
    
     
		return message; 
	} 
	
// 定义一个事件监听者,实现ApplicationListener接口,重写 onApplicationEvent() 方法; 
@Component 
public class DemoListener implements ApplicationListener<DemoEvent>{
    
     

	//使用onApplicationEvent接收消息 
	@Override 
	public void onApplicationEvent(DemoEvent event) {
    
     
		String msg = event.getMessage(); 
		System.out.println("接收到的信息是:"+msg); 
	} 
}
// 发布事件,可以通过ApplicationEventPublisher 的 publishEvent() 方法发布消息。 
@Component 
public class DemoPublisher {
    
    
	@Autowired 
	ApplicationContext applicationContext; 
	
	public void publish(String message){
    
     
		//发布事件 
		applicationContext.publishEvent(new DemoEvent(this, message)); 
	} 
}

When you call DemoPublisherthe publish()method when, for example demoPublisher.publish("你好"), the console will print out: The information received is: Hello.

Seven, adapter mode

The adapter mode ( Adapter Pattern) transforms an interface into another interface that the customer wants. The adapter mode enables classes that are incompatible with the interface to work together, and its alias is wrapper ( Wrapper).

1. Adapter mode in spring AOP

We know that the implementation of Spring AOP is based on the proxy mode, but the enhancement or advice (Advice) of Spring AOP uses the adapter mode, and the related interface is AdvisorAdapter. The commonly used types of BeforeAdviceadvice are: (before the target method is called, pre-notification), AfterAdvice(after the target method is called, post-notification), AfterReturningAdvice(after the target method is executed, before return), and so on. Each type of the Advice (notification) has a corresponding blockers: MethodBeforeAdviceInterceptor, AfterReturningAdviceAdapter, AfterReturningAdviceInterceptor. The notifications predefined by Spring should be adapted to MethodInterceptorobjects of interface (method interceptor) type (eg MethodBeforeAdviceInterceptorresponsible for adaptation MethodBeforeAdvice) through the corresponding adapter .

2. Adapter pattern in spring MVC

In Spring MVC, DispatcherServletcall according to the request information HandlerMappingand parse the corresponding request Handler. Resolved to the corresponding Handler(that is, we usually say Controllerafter the controller), starting from the HandlerAdapterprocess adapter. HandlerAdapterAs the desired interface, the specific adapter implementation class is used to adapt the target class Controlleras the class that needs to be adapted.

Why use the adapter pattern in Spring MVC? Spring MVC are Controllermany kinds and types of Controllerdifferent methods for processing by the request. If you don't use the adapter mode, you DispatcherServletcan directly obtain the corresponding type, Controllerand you need to judge by yourself, like the following code:

if(mappedHandler.getHandler() instanceof MultiActionController){
    
     
	((MultiActionController)mappedHandler.getHandler()).xxx 
}else if(mappedHandler.getHandler() instanceof XXX){
    
     
	... 
}else if(...){
    
     
	... 
}

If we add one more Controllertype of statement would then add a line judge in the above code, this form would make the program difficult to maintain, but also violated the principle of opening and closing the design mode - open to extension but closed for modification.

Eight, decorator mode

Decorator mode can dynamically add some additional properties or behaviors to the object. Compared to using inheritance, the decorator model is more flexible. To put it simply, when we need to modify the original function, but we do not want to directly modify the original code, design a Decorator to cover the original code. In fact, there are many places in the JDK uses the decorator pattern, such as InputStreamfamily, InputStreamhave lower class FileInputStream(read document), BufferedInputStream(increase the cache, greatly enhance the speed of reading the file) and other sub-classes without modifying InputStreamthe extended code case It has its function.

When configuring DataSource in Spring, DataSource may be a different database and data source. Can we dynamically switch between different data sources according to customer needs without modifying the original code? At this time, we will use the decorator mode (I don't understand the specific principles too much at this point). Spring mode used in the packaging containing the class name Wrapper, or Decorator. These classes are basically dynamically adding some additional responsibilities to an object

Nine, summary

What design patterns are used in the Spring framework?

  • Factory design pattern : Spring uses the factory pattern to pass BeanFactoryand ApplicationContextcreate bean objects.
  • Proxy design pattern : Implementation of Spring AOP function.
  • Singleton design pattern : Beans in Spring are singletons by default.
  • Template method mode : In Spring jdbcTemplateand hibernateTemplateother classes that operate on the database ending with Template, they use the template mode.
  • Wrapper design pattern : Our project needs to connect to multiple databases, and different customers will visit different databases according to their needs during each visit. This model allows us to dynamically switch between different data sources according to customer needs.
  • Observer pattern : Spring event-driven model is a classic application of the observer pattern.
  • Adapter mode : Spring AOP's enhancement or advice (Advice) uses the adapter mode, and spring MVC also uses the adapter mode adaptation Controller.
  • Welcome to add! ! !

Reference material: "Comprehensive Analysis of Java Intermediate and Advanced Core Knowledge" is limited to 100 copies. Some people have already obtained it through my previous article!
Seats are limited first come first served! ! ! There are more Java Pdf learning materials waiting for you! ! !
Students who want to get this learning material can click here to get it for free """""""

Guess you like

Origin blog.csdn.net/Java_Caiyo/article/details/111992056