The system knowledge points and interview questions of Java learning summarized by myself have been opened source and have been 41K + Star at present. Suggestions and guidance are welcome, as well as Star: github.com/Snailclimb/…

What design patterns are used in the JDK? What design patterns does Spring use? These two questions are common in the interview. I did a web search on design patterns in Spring and almost all of them are the same, and most of them are old. Therefore, I spent a few days to summarize myself. Due to my limited personal ability, you can point out any mistakes in the article. In addition, I have only scratched the surface of design patterns and some interpretation of the source code because of the limited space in this article. The main purpose of this article is to review design patterns in Spring.

Design Patterns represent the best computer programming practices in object-oriented software development. Different types of design patterns are widely used in the Spring framework. Let’s take a look at what are some of them?

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 decoupled design idea. Its main purpose is to decouple dependent objects (IOC objects are easy to manage, you just use) with the help of a “third party” (the IOC container in Spring), thus reducing the coupling between code. IOC is a principle, not a pattern, and 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 just need to configure the configuration file/annotations, regardless of how the object was created. The IOC container is responsible for creating objects, wiring them together, configuring them, and handling them throughout their life cycle from creation until they are completely destroyed.

In a real project, if a Service class has hundreds or even thousands of classes as its underlying class and we need to instantiate the Service, you might have to figure out the constructors of all the underlying classes of the Service every time, which can drive people crazy. With IOC, all you need to do is configure it and then reference it where you need it, which makes your project much more maintainable and easier to develop. On the understanding of the Spring IOC, recommend watching this zhihu one answer: www.zhihu.com/question/23… Very good.

How do you understand the flip control? For example: “Object A depends on object B and must be created when object A needs object B. However, when the system introduced the IOC container, object A and object B lost their direct connection. At this point, when object A needs object B, we can specify the IOC container to create an object B to inject into object A. The process by which object A acquires a dependent object B changes from an active behavior to a passive behavior, a reversal of control, hence the name inversion of control.

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

Factory design pattern

Spring uses the factory pattern to create bean objects through either the BeanFactory or ApplicationContext.

Comparison between the two:

  • BeanFactory: lazy injection (injected only when a bean is used), compared toBeanFactoryIt takes up less memory and launches faster.
  • ApplicationContextWhen the container starts, create all the beans at once, whether you use them or not.BeanFactoryProvides only the most basic dependency injection support,ApplicationContextExtend theBeanFactory, in addition to theBeanFactoryThere are additional features, so general developers useApplicationContextWill be more.

ApplicationContext’s three implementation classes:

  1. ClassPathXmlApplication: Treat context files as classpath resources.
  2. FileSystemXmlApplication: Loads context definition information from an XML file in the file system.
  3. XmlWebApplicationContext: Loads context definition information from an 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(); }}Copy the code

Singleton design pattern

There are some objects in our system that we really only need one: thread pools, caches, dialogs, registries, log objects, objects that act as drivers for printers, graphics cards, and other devices. In fact, there can only be one instance of this class of objects, and creating more than one instance can lead to problems such as abnormal program behavior, excessive resource usage, or inconsistent results.

Benefits of using the singleton pattern:

  • For frequently used objects, you can omit the time it takes to create them, which can be a significant overhead for heavy objects.
  • As the number of new operations is reduced, the system memory is used less frequently, which reduces GC stress and reduces GC pause times.

The default scope of a bean in Spring is that of a singleton. In addition to the Singleton scope, Spring beans have the following scopes:

  • Prototype: Each request creates a new bean instance.
  • Request: Each HTTP request generates a new bean that is valid only within the current HTTP Request.
  • Session: Each HTTP request generates a new bean that is valid only for the current HTTP session.
  • Global-session: the global session scope, which is only meaningful in portlet-based web applications, is no longer available in Spring5. Portlets are small Java Web plug-ins that can generate snippets of semantic code, such as HTML. They are based on portlet containers and can handle HTTP requests like servlets. However, unlike servlets, each portlet has a different session

Spring implements singletons in this way:

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

Spring throughConcurrentHashMapA special way to implement the singleton registry implements the singleton pattern. The core code for Spring’s singleton implementation is as follows

// Implement the singleton registry with ConcurrentHashMap (thread-safe)
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) {
            // Check if there is an instance in the cache
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                / /... A lot of code is omitted
                try {
                    singletonObject = singletonFactory.getObject();
                }
                / /... A lot of code is omitted
                // If the instance object does not exist, we register it in the singleton registry.
                addSingleton(beanName, singletonObject);
            }
            return(singletonObject ! = NULL_OBJECT ? singletonObject :null); }}// Add objects to the singleton registry
    protected void addSingleton(String beanName, Object singletonObject) {
            synchronized (this.singletonObjects) {
                this.singletonObjects.put(beanName, (singletonObject ! =null? singletonObject : NULL_OBJECT)); }}}Copy the code

Agent design pattern

Application of proxy pattern in AOP

AOP(aspect-oriented Programming: section-oriented Programming) can encapsulate the logic or responsibility (such as transaction processing, log management, permission control, etc.) that has nothing to do with business but is called jointly by business modules, so as to reduce the repeated code of the system and reduce the coupling degree between modules. And is conducive to the future scalability and maintainability.

Spring AOP is based on dynamic proxies. If you want to Proxy an object that implements an interface, Spring AOP uses JDK Proxy to create Proxy objects. If you don’t implement an interface, you can’t use JDK Proxy to Proxy objects. Spring AOP will use Cglib to generate a subclass of the proxied object as the proxy, as shown in the following figure:

You can also use AspectJ, which is already integrated with Spring AOP and is arguably the most complete AOP framework in the Java ecosystem.

With AOP, we can abstract out some common functions and use them where needed, which greatly simplifies the amount of code. It is also convenient when we need to add new features, which also improves system scalability. Logging capabilities, transaction management, and other scenarios use AOP.

What is the difference between Spring AOP and AspectJ AOP?

Spring AOP is runtime enhancement, while AspectJ is compile-time enhancement. Spring AOP is based on Proxying, while AspectJ is based on Bytecode Manipulation.

Spring AOP already integrates with AspectJ, which is arguably the most complete AOP framework in the Java ecosystem. AspectJ is more powerful than Spring AOP, but Spring AOP is relatively simple,

If we have fewer cuts, there is not much difference in performance. However, when there are too many facets, AspectJ is the best choice, which is much faster than Spring AOP.

Template method

The template method pattern is a behavior design pattern that defines the skeleton of an algorithm in an operation while deferring some steps to subclasses. The template approach allows subclasses to redefine how specific steps of an algorithm are implemented without changing the structure of that algorithm.

public abstract class Template {
    // This is our template method
    public final void TemplateMethod(a){
        PrimitiveOperation1();  
        PrimitiveOperation2();
        PrimitiveOperation3();
    }

    protected void  PrimitiveOperation1(a){
        // The current class implementation
    }
    
    // The method implemented by the subclass
    protected abstract void PrimitiveOperation2(a);
    protected abstract void PrimitiveOperation3(a);

}
public class TemplateImpl extends Template {

    @Override
    public void PrimitiveOperation2(a) {
        // The current class implementation
    }
    
    @Override
    public void PrimitiveOperation3(a) {
        // The current class implementation}}Copy the code

Spring’s jdbcTemplate, hibernateTemplate, and other classes that end in Template for database operations use the Template mode. Instead of using inheritance to implement the template pattern, Spring uses the Callback pattern in conjunction with the template method pattern to achieve code reuse and increase flexibility.

Observer model

The observer pattern is an object behavior pattern. It represents a dependency relationship between objects. When an object changes, the object it 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 in decoupling our code in many scenarios. For example, if we need to update the index every time we add an item, we can use the Observer pattern to solve this problem.

There are three roles in the Spring event-driven model

The event character

ApplicationEvent (org. Springframework. Context package) ACTS as the role of events, this is an abstract class, it inherits the Java. Util. EventObject and implements the Java IO. The Serializable interface.

Spring has the following events by default, which are implementations of ApplicationContextEvent (inherited from ApplicationContextEvent) :

  • ContextStartedEvent:ApplicationContextEvents triggered after startup;
  • ContextStoppedEvent:ApplicationContextAn event that is triggered after stopping;
  • ContextRefreshedEvent:ApplicationContextEvents that fire after initialization or refresh is complete;
  • ContextClosedEvent:ApplicationContextThe event that is triggered after closing.

Event listener role

ApplicationListener acts as an event listener. It is an interface where only one onApplicationEvent () method is defined to handle ApplicationEvent. The ApplicationListener interface class is provided as follows: So in Spring we simply implement the ApplicationListener interface and implement the onApplicationEvent() method to listen for events

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

Event publisher role

ApplicationEventPublisher served for the publisher of the event, it is also an interface.

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

    void publishEvent(Object var1);
}

Copy the code

ApplicationEventPublisher interface publishEvent () this method is implemented in the AbstractApplicationContext class, read the implementation of this method, You will find that the event actually is broadcast by ApplicationEventMulticaster out. The specific content is too much, I will not analyze it here, and I may write a separate article later.

Spring event flow summary

  1. Define an event: implement an inheritance fromApplicationEvent, and write the corresponding constructor;
  2. Define an event listener: implementationApplicationListenerInterface, overrideonApplicationEvent()Methods;
  3. Using event publishers to publish messages: YesApplicationEventPublisherpublishEvent()Method to publish messages.

Example:

// Define an event that inherits from ApplicationEvent and writes the corresponding constructor
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(a) {
         return message;
          }

    
// Define an event listener, implement the ApplicationListener interface, override the onApplicationEvent() method;
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{

    // Use onApplicationEvent to receive messages
    @Override
    public void onApplicationEvent(DemoEvent event) {
        String msg = event.getMessage();
        System.out.println("Received message is:"+msg); }}/ / publishing events, can through ApplicationEventPublisher publishEvent () method.
@Component
public class DemoPublisher {

    @Autowired
    ApplicationContext applicationContext;

    public void publish(String message){
        // Publish events
        applicationContext.publishEvent(new DemoEvent(this, message)); }}Copy the code

When calling DemoPublisher’s publish() method, such as demopublisher.publish (” hello “), the console prints: Hello.

Adapter mode

The Adapter Pattern translates one interface into another that the customer wants. The Adapter Pattern enables classes with incompatible interfaces to work together, nicknamed wrappers.

Adapter patterns in Spring AOP

We know that The implementation of Spring AOP is based on the proxy pattern, but Spring AOP enhancements or Advice use the adapter pattern and the associated interface is AdvisorAdapter. Common types of Advice include: BeforeAdvice (before target method invocation), AfterAdvice (after target method invocation), AfterReturningAdvice(after target method execution ends, before return), and so on. Each type of Advice (inform) have corresponding interceptor: MethodBeforeAdviceInterceptor, AfterReturningAdviceAdapter, AfterReturningAdviceInterceptor. Spring predefined notification to go through the corresponding adapter, adapter into the MethodInterceptor interface interceptor (method) types of objects (such as: MethodBeforeAdviceInterceptor adapter MethodBeforeAdvice).

The adapter pattern in Spring MVC

In Spring MVC, the DispatcherServlet invokes HandlerMapping based on the request information and resolves the Handler corresponding to the request. After parsing to the corresponding Handler (commonly known as the Controller Controller), it is processed by the HandlerAdapter adapter. The HandlerAdapter acts as the desired interface, the specific adapter implementation class is used to adapt the target class, and the Controller acts as the class to be adapted.

Why use the adapter pattern in Spring MVC? There are many different types of Controllers in Spring MVC, and different types of controllers handle requests in different ways. If the adapter mode is not used, the DispatcherServlet directly fetches the corresponding Controller type, as shown in the following code:

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

If we add another Controller type, we have to add another line of judgment statements to the code above, which makes the program difficult to maintain and violates the open and closed principle of design pattern-open for extension, closed for modification.

Decorator pattern

The decorator pattern can dynamically add additional properties or behaviors to an object. The decorator pattern is more flexible than using inheritance. To put it simply, design a Decorator on top of the existing code when we need to modify the existing functionality, but we don’t want to modify the existing code directly. In fact, there are many places in the JDK that use decorator patterns, such as the InputStream family, The InputStream subclasses FileInputStream (reads files) and BufferedInputStream (increases the cache and reads files faster) extend the functionality of InputStream without modifying the InputStream code.

When configuring a DataSource in Spring, the DataSource may be a different database and DataSource. Can we dynamically switch between different data sources according to customer needs with less modification of the original class code? This is where decorator mode comes in (which I don’t quite understand myself). The Wrapper pattern used in Spring has a Wrapper or Decorator on the class name. These classes basically add extra responsibilities to an object on the fly

conclusion

What design patterns are used in the Spring framework?

  • Factory design pattern: Spring uses factory mode to passBeanFactory,ApplicationContextCreate the bean object.
  • Proxy design pattern: Implementation of Spring AOP functionality.
  • Singleton design pattern: Beans in Spring are singleton by default.
  • Template method pattern: in the SpringjdbcTemplate,hibernateTemplateClasses that operate on databases that end in Template use the Template pattern.
  • Wrapper design pattern: Our project needs to connect to multiple databases, and different customers need to access different databases on each visit. This pattern allows us to dynamically switch between different data sources based on customer needs.
  • Observer Pattern: The Spring event-driven model is a classic application of the Observer pattern.
  • Adapter modeThe adaptor pattern is used in Spring AOP enhancements or Advice, and adaptor pattern adaptation is used in Spring MVCController.
  • .

reference

  • Inside Spring Technology
  • Blog.eduonix.com/java-progra…
  • Blog. Yeamin. Top / 2018/03/27 /…
  • www.tutorialsteacher.com/ioc/inversi…
  • The design – patterns. Readthedocs. IO/zh_CN/lates…
  • Juejin. Cn/post / 684490…
  • Juejin. Cn/post / 684490…

The public,

If you want to follow my updated articles and shared dry goods in real time, you can follow my official account.

“Java interview assault “: derived from this document designed for the interview and born of the “Java interview assault” V2.0 PDF version of the public number background reply “Java interview assault “can be free!

Necessary learning resources for Java engineers: Some Java engineers commonly use learning resources public account background reply keyword “1” can be free of routine access.