1. Implementation of simple factory (not one of the 23 design patterns) :

The BeanFactory. The BeanFactory in Spring is an embodiment of the simple factory pattern. Bean objects are obtained by passing in a unique identifier, but whether this is created after or before the parameters are passed in depends on the case. Substance:

A factory class dynamically decides which product class should be created based on the parameters passed in. Implementation principle:

The bean container startup phase:

  • Read the BEAN’s XML configuration file and convert each bean element into a BeanDefinition object.
  • These beans are then registered with the beanFactory via the BeanDefinitionRegistry and stored in one of its ConcurrentHashMap.
  • After registering the BeanDefinition with the beanFactory, Spring provides us with an extended notch where we can insert our defined code by implementing the interface BeanFactoryPostProcessor. Typical example is that: is accomplished, we generally in the configuration database of the dataSource is used when the placeholder value, is injected into it.

The bean instantiation phase in the container:

In the instantiation phase, where beans are instantiated via reflection or CGLIB, Spring exposes a number of extension points:

  • Various Aware interfaces, such as BeanFactoryAware, will help us inject instances of BeanFactory when instantiating beans that implement these Aware interfaces.
  • The BeanPostProcessor interface is a bean that implements the BeanPostProcessor interface. Spring will call the methods in the interface for us when instantiating the bean.
  • InitializingBean interface, the bean that implements the InitializingBean interface, Spring will call the methods in the interface for us when instantiating the bean.
  • DisposableBean interface, a bean that implements the BeanPostProcessor interface, and Spring will call the methods of this interface for us when the bean dies.

Design Significance:

Loose coupling: The original hard-coded dependencies can be injected through the Spring beanFactory. In other words, there were only dependent and dependent parties before. Now we introduce the third party — Spring beanFactory, which solves the dependency problem between beans and achieves the effect of loose coupling.

Additional processing of the bean: With the exposure of the Spring interface, we can perform some additional processing during the instantiation phase of the bean by simply having the bean implement the corresponding interface. Spring then calls the interface we implemented to process the bean during its life cycle. [Very important]

2. Implementation of factory method:

FactoryBean interface. Implementation principle:

Beans that implement the FactoryBean interface are a class of beans called Factory. The trick is that spring automatically calls the bean’s getObject() method when it gets the bean using the getBean() call, so instead of returning the factory bean, it returns the bean.getojbect () method’s return value. Example:

A good example is the combination of Spring and Mybatis. Code examples:

Description:

We see above the bean, because the FactoryBean interface, so the returned not SqlSessionFactoryBean instance, but its SqlSessionFactoryBean. GetObject () returns a value.

3. Singleton mode

Spring dependency injection Bean instances are singletons by default.

Spring’s dependency injection (including lazy-init) takes place in AbstractBeanFactory’s getBean. The doGetBean method of getBean calls getSingleton to create the bean. Analyze the getSingleton() method

3. Singleton mode

Spring dependency injection Bean instances are singletons by default.

Spring’s dependency injection (including lazy-init) takes place in AbstractBeanFactory’s getBean. The doGetBean method of getBean calls getSingleton to create the bean.

Analyze the getSingleton() method

Public Object getSingleton(String beanName){public Object getSingleton(String beanName,true) {getSingleton(String beanName,true); } protected Object getSingleton(String beanName, Boolean allowEarlyReference) {/ / check whether there is in the cache instance Object singletonObject = this. SingletonObjects. Get (beanName); If (singletonObject = = null && isSingletonCurrentlyInCreation (beanName)) {/ / if is empty, the locking global variables and processing. Synchronized (enclosing singletonObjects) {/ / if the beans are loaded, does not handle singletonObject = this. EarlySingletonObjects. Get (beanName); If (singletonObject == null && allowEarlyReference) {// addSingleFactory is called when some methods need to be pre-initialized Method stores the corresponding ObjectFactory initialization policy in singletonFactories ObjectFactory<? > singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory ! = null) {/ / call the pre-set singletonObject = singletonFactory getObject method. The getObject (); / / records in the cache, earlysingletonObjects and the enclosing singletonFactories earlysingletonObjects. Put (beanName singletonObject); this.singletonFactories.remove(beanName); } } } } return (singletonObject ! = NULL_OBJECT ? singletonObject : null); }Copy the code

Figure getSingleton () process

Ps: Spring uses the singleton pattern of double judgment locking for dependency injection

conclusion

Singleton pattern definition: Guarantees that a class has only one instance and provides a global access point to access it.

Spring’s implementation of singletons: The singleton pattern in Spring does the rest, providing a global access point to the BeanFactory. But you don’t control the singleton from the constructor level, because Spring manages arbitrary Java objects.

4. Adapter mode

  • Implementation: The adapter HandlerAdatper in SpringMVC.

  • Implementation principle: HandlerAdatper Executes different handlers based on Handler rules.

  • Implementation process: The DispatcherServlet sends a request to the HandlerAdatper based on the handler returned by HandlerMapping and processes the Handler.

The HandlerAdapter finds the corresponding Handler based on the rule and tells it to execute, and then returns a ModelAndView to the HandlerAdapter, Finally, the HandlerAdapter returns a ModelAndView to the DispatchServelet.

  • Implementation significance: HandlerAdatper makes it easy to extend handlers by adding a new Handler and a corresponding HandlerAdapter.

So Spring defines an adaptation interface so that each Controller has a corresponding adapter implementation class that performs the corresponding methods instead of the Controller. When you extend Controller, you only need to add an adapter class to complete the extension of SpringMVC.

5. Implementation mode of decorator mode:

The Wrapper pattern used in Spring has two representations on class names: one with a Wrapper in the class name and one with a Decorator in the class name. Substance:

Add some extra responsibilities to an object dynamically.

The Decorator pattern is more flexible in terms of adding functionality than subclassing.

6. Implementation of proxy mode:

AOP bottom layer, is the implementation of the dynamic proxy pattern. Dynamic proxy:

Static proxies built in memory without the need to manually write proxy classes:

You need to manually write proxy classes that refer to proxied objects. Implementation principle:

The facets are woven in at the time the application runs. Typically, the AOP container dynamically creates a proxy object for the target object when weaving into the cut. SpringAOP is woven into the facets in this way.

Weaving: The process of applying a facet to a target object and creating a new proxy object.

7. Implementation mode of observer mode:

Spring’s event-driven model uses the Observer pattern, and a common place in Spring for the Observer pattern is the listener implementation. Concrete implementation:

The implementation of event mechanism needs three parts: event source, event and event listener

ApplicationEvent Abstract class [event]

Inheriting from the JDK’s EventObject, all events need to inherit ApplicationEvent and get the event source from the constructor parameter source.

The implementation class ApplicationContextEvent represents the container event of ApplicaitonContext.

Code:

public abstract class ApplicationEvent extends EventObject { private static final long serialVersionUID = 7099057708183571937L; private final long timestamp; public ApplicationEvent(Object source) { super(source); this.timestamp = System.currentTimeMillis(); } public final long getTimestamp() { return this.timestamp; }}Copy the code

ApplicationListener interface [event Listener]

Inheriting from the JDK EventListener, all listeners implement this interface.

This interface has only one onApplicationEvent() method, which takes an ApplicationEvent or one of its subclasses as an argument. Within the method body, different judgments of the Event class can be processed accordingly.

All listeners receive messages when an event is triggered.

Code:

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
     void onApplicationEvent(E event);
}
Copy the code

ApplicationContext interface [Event source]

ApplicationContext is the global container in spring, which translates to “ApplicationContext”.

ApplicationEventPublisher interface is realized.

Responsibilities:

It is responsible for reading bean configuration documents, managing bean loading, maintaining dependencies between beans, and the whole life cycle of beans. In a more general way, it is also known as the IOC container. Code:

public interface ApplicationEventPublisher {
        void publishEvent(ApplicationEvent event);
}

public void publishEvent(ApplicationEvent event) {
    Assert.notNull(event, "Event must not be null");
    if (logger.isTraceEnabled()) {
         logger.trace("Publishing event in " + getDisplayName() + ": " + event);
    }
    getApplicationEventMulticaster().multicastEvent(event);
    if (this.parent != null) {
    this.parent.publishEvent(event);
    }
}
Copy the code

ApplicationEventMulticaster abstract class publishEvent method need to call the method in [the event source getApplicationEventMulticaster]

Applicationcontext is an Event broadcaster that broadcasts events published by Applicationcontext to all listeners.

Code:

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean { private ApplicationEventMulticaster applicationEventMulticaster; protected void registerListeners() { // Register statically specified listeners first. for (ApplicationListener<? > listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String lisName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(lisName); }}}Copy the code

8. Strategic mode

Implementation method:

The Spring framework’s Resource access Resource interface. This interface provides greater access to resources, and the Spring framework itself makes extensive use of the Resource interface to access underlying resources. Resource Interface introduction

The Source interface is an abstraction of a concrete resource access policy and is implemented by all resource access classes.

The Resource interface provides the following methods:

GetInputStream () : Locates and opens the resource and returns the input stream corresponding to the resource. Each call returns a new input stream. The caller must be responsible for closing the input stream. Exists () : returns whether the Resource referred to by Resource exists. IsOpen () : returns whether the resource file isOpen. If the resource file cannot be read more than once, it should be explicitly closed at the end of each read to prevent resource leakage. GetDescription () : Returns the description of the resource. It is usually used to output this information in the event of a resource processing error, usually the fully qualified filename or the actual URL. GetFile: Returns the File object corresponding to the resource. GetURL: Returns the URL object corresponding to the resource.

The last two methods are usually not needed, and Resource provides traditional Resource access only when simple access is not possible.

The Resource interface itself does not provide implementation logic for accessing any of the underlying resources. Spring will provide different Resource implementation classes for different underlying resources, and each implementation class is responsible for different Resource access logic.

Spring provides the following implementation classes for the Resource interface:

UrlResource: Implementation class for accessing network resources. ClassPathResource: Implementation class that accesses resources in the classload path. FileSystemResource: Implementation class for accessing resources in a file system. ServletContextResource: Implementation class that accesses resources relative to the ServletContext path. InputStreamResource: Implementation class that accesses input stream resources. ByteArrayResource: Implementation class that accesses byte array resources.

These Resource implementation classes, for different underlying resources, provide the corresponding Resource access logic, and provide convenient packaging, to facilitate the client program Resource access.

9. Classic template method definitions:

The parent class defines the skeleton (which methods to call and in what order), and certain methods are implemented by subclasses.

Biggest benefit: code reuse, reduce duplicate code. Methods and the order in which they are called are written in advance in the parent class, except for the specific methods that the subclass implements.

So there are two classes of superclass template methods:

Common method: code used by all subclasses

Different methods: Subclasses override methods, divided into two types:

Abstract method: the parent class is an abstract method, and the subclass must override the hook method: the parent class is an empty method, and the subclass inherits the default empty method

A subclass can use this hook to control its parent class because the hook is actually an empty method of the parent class. The essence of the Spring template method pattern

Is a combination of the Template Method pattern and the callback pattern, and is another implementation of the Template Method that does not need to inherit. Almost all of Spring’s add-ons follow this pattern. Concrete implementation:

JDBC abstraction and Hibernate integration both take the idea or approach of combining the template method pattern with the corresponding Callback interface.

The template method pattern is used to handle resource acquisition and release in a unified and centralized way. Take JdbcTempalte as an example:

Public final Object Execute (String SQL) {Connection con=null; Statement stmt=null; Try {con=getConnection (); STMT = con. CreateStatement (); Object retValue=executeWithStatement (STMT, SQL); return retValue; }catch (SQLException e) {... }finally{closeStatement (STMT); ReleaseConnection (con); }} protected abstract Object executeWithStatement (Statement STMT, String SQL); }Copy the code

The reason for introducing the callback:

The JdbcTemplate class is abstract and cannot be used independently. It is not convenient to give a corresponding subclass implementation every time we perform data access, so we introduced the callback.

The callback code

Public interface StatementCallback{Object doWithStatement (Statement STMT); }Copy the code

Override the JdbcTemplate method with a callback method

Public class JdbcTemplate {public Final Object execute (StatementCallback callback) {Connection con=null; Statement stmt=null; Try {con=getConnection (); STMT = con. CreateStatement (); Object retValue=callback.doWithStatement (STMT); return retValue; }catch (SQLException e) {... }finally{closeStatement (STMT); ReleaseConnection (con); }}... // Other method definitions}Copy the code

The Jdbc usage is as follows:

JdbcTemplate jdbcTemplate=... ; final String sql=... ; StatementCallback callback=new StatementCallback(){ public Object=doWithStatement(Statement stmt){ return ... ; } } jdbcTemplate.execute(callback);Copy the code

Why doesn’t JdbcTemplate use inheritance?

This class has too many methods, but we still want to use the stable, common database connection that JdbcTemplate already has, so what do we do?

We can pull out the change and pass it as a parameter to the JdbcTemplate method. But what changes is a piece of code, and that code uses variables in the JdbcTemplate. How to do?

So let’s use callback objects. Define a method in the callback object that manipulates the variables in the JdbcTemplate, and we implement this method to concentrate the changes here. We then pass the callback object to the JdbcTemplate to complete the call. From: zhuanlan.zhihu.com/p/144245915