High-intensity learning and training fifteenth day summary: Spring Framework design patterns

Careful thought. . No need to repeat-create the wheel.
What a day to review the direct CTRL CV

https://gitee.com/SnailClimb/JavaGuide/blob/master/docs/system-design/framework/spring/Spring-Design-Patterns.md#

Inversion of Control (IoC) and dependency injection (DI)

IoC (Inversion of Control, control flip) is Spring in a very, very important concept, it is not a technology, but a decoupled design. Its main purpose is to achieve decoupling between objects having dependency by means of "third party" (Spring container in the IOC) (the IOC easy to manage objects, you can just use), thereby reducing the coupling between the code . IOC is a principle, instead of a pattern, the following modes (but not limited to) the IoC principle achieved.

Spring IOC container are like a factory, when we need to create an object, you can just configure the configuration file / annotation can be, no need to consider how objects are created out of. IOC container is responsible for creating objects, connect objects together, configure these objects, and to process the entire lifecycle from the creation of these objects until they are completely destroyed.

In a real project a Service class if there are hundreds or even thousands of class as its bottom, we need to instantiate the Service, you may want to find out every time the constructor of this Service all the underlying class, which could put people crazy. If the use of the IOC, you only need to configure, and where necessary quoted on the line, which greatly increases the maintainability of the project and reduce the development effort. About Spring IOC understanding, it is recommended to see which look almost know one answer: https://www.zhihu.com/question/23277575/answer/169698662 , very good.

? Control Flip how to understand it give an example: "Object a dependent object b, when the object is a need to use the object b must be to create their own but when the system was introduced IOC container, before the object a and object b lost. a direct link. this time, when the object is a need to use the object b, we can specify the IOC container to create an object b injected into a subject in. " The process of obtaining a target dependent objects b by the proactive behavior becomes a passive behavior, control of the flip, the origin of which is to control the reversal of the name.

DI (Dependecy Inject, dependency injection) is controlled to achieve a design pattern is inverted, that is the instance variable dependency injection into an object to pass.

Factory design pattern

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

Comparison between the two:

  • BeanFactory: Delayed implantation (when using the bean will be injected to a), compared to BeanFactorywho will take up less memory, programs start faster.
  • ApplicationContext: Container startup, whether you use to useless, disposable create all 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.

ApplicationContext realization of three categories:

  1. ClassPathXmlApplication: Document as the context classpath resources.
  2. FileSystemXmlApplication: Loaded from the file system XML file context definition information.
  3. XmlWebApplicationContext: Load context definition information from the Web system in XML files.

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();
    }
}

Singleton design pattern

In our system, there are some objects in fact, we only need one, for example: the thread pool, cache, dialog, registry, log object, the object serves as a device driver for your printer, graphics and so on. In fact, this type of object can only have one instance, if you create multiple instances of it could lead to some problems, such as: abnormal behavior of the program, and the resource overage, or inconsistency of the results.

The benefits of using Singleton pattern:

  • For frequently used objects, you can create omit the time it takes an object, which for those heavyweight objects, is very respectable amount of system overhead;
  • Due to the reduced number of new operations, and thus the frequency of use of system memory will be reduced, which will relieve pressure GC, GC pause times shortened.

The default scope in Spring bean is singleton (single example). In addition to the singleton scope, Spring bean in scope as well as the following categories:

  • prototype: every request to create a new bean instance.
  • request: Each HTTP request will generate a new bean, which is only valid in the current HTTP request.
  • session: Each HTTP request will generate a new bean, which is only valid in the current HTTP session.
  • global-session: the global session scope, only the portlet web-based application makes sense, Spring5 gone. Portlet is capable of generating a semantic code (eg: HTML) Small Java Web plugin fragments. They are based portlet container may be treated as HTTP servlet request like. However, the servlet different, each has a different portlet session

Example implementations of a single Spring:

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

Spring by ConcurrentHashMapsingle-mode specific embodiments manner singleton registry. Spring core code implemented as a single embodiment of

// 通过 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));

            }
        }
}

Proxy design pattern

Application proxy mode in the AOP

AOP (Aspect-Oriented Programming: Oriented Programming) can be those regardless of the service, but a logical or liabilities (such as transaction processing, log management, access control, etc.) service module jointly called encapsulated , to facilitate code duplication reduction system , to reduce the coupling between modules , and is conducive to the future scalability and maintainability .

Spring AOP is the dynamic agent-based , if you want to proxy object implements an interface, then Spring AOP will use JDK Proxy , to create a proxy object, but the object does not implement an interface, you can not use the JDK Proxy to proxy the this time Spring AOP uses Cglib , this time Spring AOP uses Cglib generating a subclass of the object as a proxy agent, as shown below:

SpringAOPProcess

Of course, you can also use AspectJ, Spring AOP has been integrated with AspectJ, AspectJ should be counted on the Java ecosystem is the most complete of the AOP framework.

After using AOP we can put some common functions abstracted, use can be used directly where it is needed, which greatly simplifies the code amount. It is also convenient when we need to add new features, which would also increase the scalability of the system. Logging, transaction management, and so on scene have used the AOP.

Spring AOP and AspectJ AOP What is the difference?

Enhanced belonging run Spring AOP, and AspectJ is an enhanced compilation. Spring AOP based agent (Proxying), based on the AspectJ bytecode manipulation (Bytecode Manipulation).

Spring AOP has been integrated with AspectJ, AspectJ should be counted on the Java ecosystem is the most complete of the AOP framework. Spring AOP AspectJ compared to the more powerful, but Spring AOP relatively more simple,

If we cut surface is relatively small, so little performance difference between the two. However, when cut too much, the best choice for AspectJ, it is much faster than Spring AOP.

Template Method

Template Method design pattern is a behavioral pattern that defines a skeleton of the algorithm operation, some steps to subclasses delay. Template Method lets subclasses may not change the structure of an algorithm to redefine certain steps of the implementation of the algorithm.

Template Method UML diagrams

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, hibernateTemplateor the like to the end of the class Template database operations, they are used to model the template. Under normal circumstances, we are achieved using template inheritance pattern of the way, but Spring does not use this method, but using Callback Mode and Template Method pattern fit only achieve the effect of code reuse, as well as increased flexibility .

Observer Pattern

The observer pattern is an object behavioral patterns. It indicates the kind of object having a dependency between the object and, when an object is changed, the object of the dependent object will respond. Spring event-driven model is the Observer pattern of a classic application. Spring event-driven model is very useful in many scenarios can decouple our code. For example, every time we add commodities when they are required to re-update commodity index, this time we can use the observer pattern to solve this problem.

Spring event-driven model of the three roles

Events 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 the start;
  • ContextStoppedEvent: ApplicationContextEvent after triggering stop;
  • ContextRefreshedEvent: ApplicationContextInitialization or refresh event after the completion of the trigger;
  • ContextClosedEvent: ApplicationContextEvent-triggered after closing.

ApplicationEvent-Subclass

Event listener role

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);
}

Event Publisher role

ApplicationEventPublisher Served as 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. Specific content too much, not analyzed here, behind might write a separate article mentioned.

Spring flow of events summary

  1. Define an event: a realization inherits from 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: 接收到的信息是:你好.

Adapter mode

Adapter mode (Adapter Pattern) to a desired conversion interface into another interface to the client, so that the class interface adapter mode may be incompatible with the work, which alias wrapper (Wrapper).

The adapter mode spring AOP

We know that to achieve Spring AOP is based on proxy mode, but Spring AOP enhancements or notification (Advice) to use the adapter mode, the associated interface is AdvisorAdapter. Advice common types are: BeforeAdvice(before the target method call, pre-notification), AfterAdvice(after the target method invocation, after advice), AfterReturningAdvice(after the execution of the target method, before the return) and so on. Each type of the Advice (notification) has a corresponding blockers: MethodBeforeAdviceInterceptor, AfterReturningAdviceAdapter, AfterReturningAdviceInterceptor. Spring predefined notification through the corresponding adapter, adapted to MethodInterceptorthe type of object interface (Method interceptor) (eg: MethodBeforeAdviceInterceptorin charge of adapting MethodBeforeAdvice).

spring MVC in adapter mode

In the Spring MVC, DispatcherServletaccording to call request information HandlerMapping, corresponding to the resolution request Handler. Resolved to the corresponding Handler(that is, we usually say Controllerafter the controller), starting from the HandlerAdapterprocess adapter. HandlerAdapterAs a desired interface implementation class specific adapter for adapting the target class, Controllera class adapter required.

Why use Spring MVC in adapter mode? Spring MVC are Controllermany kinds and types of Controllerdifferent methods for processing by the request. If not, then the use of the adapter mode, DispatcherServletdirect access to a corresponding type Controller, it is necessary to self-determination, the same code as follows:

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.

Decorator Pattern

The decorator pattern to an object can dynamically add some additional attributes or behavior. Compared to the use of inheritance, the decorator pattern is more flexible. Simple little say is that when we need to modify the original function, but we do not want to go directly to modify the original code, the original design of the code outside a Decorator sets in. 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 its functionality.

The decorator pattern schematic

Spring 中配置 DataSource 的时候,DataSource 可能是不同的数据库和数据源。我们能否根据客户的需求在少修改原有类的代码下动态切换不同的数据源?这个时候就要用到装饰者模式(这一点我自己还没太理解具体原理)。Spring 中用到的包装器模式在类名上含有 Wrapper或者 Decorator。这些类基本上都是动态地给一个对象添加一些额外的职责

总结

Spring 框架中用到了哪些设计模式?

  • 工厂设计模式 : Spring使用工厂模式通过 BeanFactoryApplicationContext 创建 bean 对象。
  • 代理设计模式 : Spring AOP 功能的实现。
  • 单例设计模式 : Spring 中的 Bean 默认都是单例的。
  • 模板方法模式 : Spring 中 jdbcTemplatehibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
  • 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
  • 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
  • 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller
  • ......

参考

Guess you like

Origin www.cnblogs.com/godoforange/p/11613969.html