Spring 行为模式 + 创造模式实现

维基百科:软件设计模式

Software design pattern

Creational patterns[edit]

Name Description In Design Patterns In Code Complete[13] Other
Abstract factory Provide an interface for creating families of related or dependent objects without specifying their concrete classes. Yes Yes N/A
Builder Separate the construction of a complex object from its representation, allowing the same construction process to create various representations. Yes No N/A
Dependency Injection A class accepts the objects it requires from an injector instead of creating the objects directly. No No N/A
Factory method Define an interface for creating a single object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. Yes Yes N/A
Lazy initialization Tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. This pattern appears in the GoF catalog as “virtual proxy”, an implementation strategy for the Proxy pattern. No No PoEAA[14]
Multiton Ensure a class has only named instances, and provide a global point of access to them. No No N/A
Object pool Avoid expensive acquisition and release of resources by recycling objects that are no longer in use. Can be considered a generalisation of connection pool and thread pool patterns. No No N/A
Prototype Specify the kinds of objects to create using a prototypical instance, and create new objects from the ‘skeleton’ of an existing object, thus boosting performance and keeping memory footprints to a minimum. Yes No N/A
Resource acquisition is initialization (RAII) Ensure that resources are properly released by tying them to the lifespan of suitable objects. No No N/A
Singleton Ensure a class has only one instance, and provide a global point of access to it. Yes Yes N/A

Structural patterns[edit]

Name Description In Design Patterns In Code Complete[13] Other
Adapter, Wrapper, or Translator Convert the interface of a class into another interface clients expect. An adapter lets classes work together that could not otherwise because of incompatible interfaces. The enterprise integration pattern equivalent is the translator. Yes Yes N/A
Bridge Decouple an abstraction from its implementation allowing the two to vary independently. Yes Yes N/A
Composite Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. Yes Yes N/A
Decorator Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality. Yes Yes N/A
Extension object Adding functionality to a hierarchy without changing the hierarchy. No No Agile Software Development, Principles, Patterns, and Practices[15]
Facade Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. Yes Yes N/A
Flyweight Use sharing to support large numbers of similar objects efficiently. Yes No N/A
Front controller The pattern relates to the design of Web applications. It provides a centralized entry point for handling requests. No No J2EE Patterns[16] PoEAA[17]
Marker Empty interface to associate metadata with a class. No No Effective Java[18]
Module Group several related elements, such as classes, singletons, methods, globally used, into a single conceptual entity. No No N/A
Proxy Provide a surrogate or placeholder for another object to control access to it. Yes No N/A
Twin [19] Twin allows modeling of multiple inheritance in programming languages that do not support this feature. No No N/A

Behavioral patterns[edit]

Name Description In Design Patterns In Code Complete[13] Other
Blackboard Artificial intelligence pattern for combining disparate sources of data (see blackboard system) No No N/A
Chain of responsibility Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. Yes No N/A
Command Encapsulate a request as an object, thereby allowing for the parameterization of clients with different requests, and the queuing or logging of requests. It also allows for the support of undoable operations. Yes No N/A
Interpreter Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. Yes No N/A
Iterator Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. Yes Yes N/A
Mediator Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it allows their interaction to vary independently. Yes No N/A
Memento Without violating encapsulation, capture and externalize an object’s internal state allowing the object to be restored to this state later. Yes No N/A
Null object Avoid null references by providing a default object. No No N/A
Observer or Publish/subscribe Define a one-to-many dependency between objects where a state change in one object results in all its dependents being notified and updated automatically. Yes Yes N/A
Servant Define common functionality for a group of classes. The servant pattern is also frequently called helper class or utility class implementation for a given set of classes. The helper classes generally have no objects hence they have all static methods that act upon different kinds of class objects. No No N/A
Specification Recombinable business logic in a Boolean fashion. No No N/A
State Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. Yes No N/A
Strategy Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. Yes Yes N/A
Template method Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure. Yes Yes N/A
Visitor Represent an operation to be performed on the elements of an object structure. Visitor lets a new operation be defined without changing the classes of the elements on which it operates. Yes No N/A

Concurrency patterns[edit]

Name Description In POSA2[20] Other
Active Object Decouples method execution from method invocation that reside in their own thread of control. The goal is to introduce concurrency, by using asynchronous method invocation and a scheduler for handling requests. Yes N/A
Balking Only execute an action on an object when the object is in a particular state. No N/A
Binding properties Combining multiple observers to force properties in different objects to be synchronized or coordinated in some way.[21] No N/A
Compute kernel The same calculation many times in parallel, differing by integer parameters used with non-branching pointer math into shared arrays, such as GPU-optimized Matrix multiplication or Convolutional neural network. No N/A
Double-checked locking Reduce the overhead of acquiring a lock by first testing the locking criterion (the ‘lock hint’) in an unsafe manner; only if that succeeds does the actual locking logic proceed.Can be unsafe when implemented in some language/hardware combinations. It can therefore sometimes be considered an anti-pattern. Yes N/A
Event-based asynchronous Addresses problems with the asynchronous pattern that occur in multithreaded programs.[22] No N/A
Guarded suspension Manages operations that require both a lock to be acquired and a precondition to be satisfied before the operation can be executed. No N/A
Join Join-pattern provides a way to write concurrent, parallel and distributed programs by message passing. Compared to the use of threads and locks, this is a high-level programming model. No N/A
Lock One thread puts a “lock” on a resource, preventing other threads from accessing or modifying it.[23] No PoEAA[14]
Messaging design pattern (MDP) Allows the interchange of information (i.e. messages) between components and applications. No N/A
Monitor object An object whose methods are subject to mutual exclusion, thus preventing multiple objects from erroneously trying to use it at the same time. Yes N/A
Reactor A reactor object provides an asynchronous interface to resources that must be handled synchronously. Yes N/A
Read-write lock Allows concurrent read access to an object, but requires exclusive access for write operations. No N/A
Scheduler Explicitly control when threads may execute single-threaded code. No N/A
Thread pool A number of threads are created to perform a number of tasks, which are usually organized in a queue. Typically, there are many more tasks than threads. Can be considered a special case of the object pool pattern. No N/A
Thread-specific storage Static or “global” memory local to a thread. Yes N/A

维基百科:23 种 GOF 23 种设计模式

Design_Patterns

Patterns by Type[edit]

Creational[edit]

Main article: Creational pattern

Creational patterns are ones that create objects for you, rather than having you instantiate objects directly. This gives your program more flexibility in deciding which objects need to be created for a given case.

Structural[edit]

These concern class and object composition. They use inheritance to compose interfaces and define ways to compose objects to obtain new functionality.

  • Adapter allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class.
  • Bridge decouples an abstraction from its implementation so that the two can vary independently.
  • Composite composes zero-or-more similar objects so that they can be manipulated as one object.
  • Decorator dynamically adds/overrides behaviour in an existing method of an object.
  • Facade provides a simplified interface to a large body of code.
  • Flyweight reduces the cost of creating and manipulating a large number of similar objects.
  • Proxy provides a placeholder for another object to control access, reduce cost, and reduce complexity.

Behavioral[edit]

Most of these design patterns are specifically concerned with communication between objects.

  • Chain of responsibility delegates commands to a chain of processing objects.
  • Command creates objects which encapsulate actions and parameters.
  • Interpreter implements a specialized language.
  • Iterator accesses the elements of an object sequentially without exposing its underlying representation.
  • Mediator allows loose coupling between classes by being the only class that has detailed knowledge of their methods.
  • Memento provides the ability to restore an object to its previous state (undo).
  • Observer is a publish/subscribe pattern which allows a number of observer objects to see an event.
  • State allows an object to alter its behavior when its internal state changes.
  • Strategy allows one of a family of algorithms to be selected on-the-fly at runtime.
  • Template method defines the skeleton of an algorithm as an abstract class, allowing its subclasses to provide concrete behavior.
  • Visitor separates an algorithm from an object structure by moving the hierarchy of methods into one object.

行为模式

责任链模式

我们可以认为是它是一个链一样的东西。

handler -> handler -> handler

img

Java

File.listFiles() 可以去过滤一些东西

java.io.File#listFiles()

1
2
3
4
5
6
7
8
9
public File[] listFiles(FilenameFilter filter) {
    String ss[] = list();
    if (ss == null) return null;
    ArrayList<File> files = new ArrayList<>();
    for (String s : ss)
        if ((filter == null) || filter.accept(this, s))
            files.add(new File(s, this));
    return files.toArray(new File[files.size()]);
}
  • FileFilter
  • FilenameFilter

Servlet API

FilerChain Filter -> Filter -> Filter

org.apache.catalina.core.ApplicationFilterChain#filters

apche tomcat 缓存了多个 filter ,记录每个位置,然后,

dofilter 的时候,控制它的游标往下走。

org.apache.catalina.core.ApplicationFilterChain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];

private void internalDoFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
    if (this.pos < this.n) {
        // 记录了游标
        ApplicationFilterConfig filterConfig = this.filters[this.pos++];
        try {
            Filter filter = filterConfig.getFilter();
            if (request.isAsyncSupported() && "false".equalsIgnoreCase(filterConfig.getFilterDef().getAsyncSupported())) {
                request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", Boolean.FALSE);
            }

            if (Globals.IS_SECURITY_ENABLED) {
                Principal principal = ((HttpServletRequest)request).getUserPrincipal();
                Object[] args = new Object[]{request, response, this};
                SecurityUtil.doAsPrivilege("doFilter", filter, classType, args, principal);
            } else {
                filter.doFilter(request, response, this);
            }

        }
        //。。。。
    }
}

每次取出来,然后去执行。

fiter 调用 #doFilter 的时候,就会一层一层的往下走。

Spring MVC

HandlerMapping (拦截器来源,配置)

HandlerExecutionChain(执行来源,不是每一个请求都会进去。这个请求匹配上的时候,挑选一点出来。)

HandlerInterceptor -> HandlerInterceptor -> HandlerInterceptor

上边是一定执行。

MappedInterceptor 映射接口(这个是想想在执行,)

org.springframework.web.servlet.handler.AbstractHandlerMapping

1
2
3
4
5
private final List<Object> interceptors = new ArrayList();
// 没办法替换,只能追加
public void setInterceptors(Object... interceptors) {
    this.interceptors.addAll(Arrays.asList(interceptors));
}

org.springframework.web.servlet.HandlerExecutionChain : 包含了我们的请求的执行链。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
    HandlerExecutionChain chain = handler instanceof HandlerExecutionChain ? (HandlerExecutionChain)handler : new HandlerExecutionChain(handler);
    String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
    Iterator var5 = this.adaptedInterceptors.iterator();

    while(var5.hasNext()) {
        HandlerInterceptor interceptor = (HandlerInterceptor)var5.next();
        if (interceptor instanceof MappedInterceptor) {
            MappedInterceptor mappedInterceptor = (MappedInterceptor)interceptor;
            // 会匹配我们的请求,动态的计算
            if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
                chain.addInterceptor(mappedInterceptor.getInterceptor());
            }
        } else {
            chain.addInterceptor(interceptor);
        }
    }

    return chain;
}

org.springframework.web.servlet.HandlerExecutionChain

1
2
3
4
5
6
7
public class HandlerExecutionChain {
    private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
    private final Object handler;
    @Nullable
    private HandlerInterceptor[] interceptors;
    @Nullable
    private List<HandlerInterceptor> interceptorList;

兼容性的问题,主要问题是看方法兼容不兼容,因为它的封装性,所以内部变不变是无所谓的。

  • 数组,扩展数组不方便。

Spring WebFlux

org.springframework.web.server.WebFilter

1
2
3
public interface WebFilter {
    Mono<Void> filter(ServerWebExchange var1, WebFilterChain var2);
}

也是一种责任链模式。

org.springframework.web.server.ServerWebExchange

1
2
3
4
5
6
7
public interface ServerWebExchange {
    String LOG_ID_ATTRIBUTE = ServerWebExchange.class.getName() + ".LOG_ID";

    ServerHttpRequest getRequest();

    ServerHttpResponse getResponse();
    

命令模式 Command

维基百科

Command pattern

img

RestTemplate

org.springframework.web.client.RestTemplate#execute(.......)

命令模式一般都是 有 #execute 方法。

HttpInvokerServiceExporter

org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter

简单的命令模式

org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor

1
2
3
4
5
6
7
8
protected RemoteInvocationResult doExecuteRequest(HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws IOException, ClassNotFoundException {
    HttpURLConnection con = this.openConnection(config);
    this.prepareConnection(con, baos.size());
    this.writeRequestBody(config, con, baos);
    this.validateResponse(config, con);
    InputStream responseBody = this.readResponseBody(config, con);
    return this.readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
}

拦截器模式

Interpreter pattern

HandlerInterceptor 就是拦截。(Spring Web MVC 种)

Spring AOP 代理(Java 动态代理、Cglib)

  • Spring Cache -> @Cache -> CacheInterceptor
  • Spring Transaction -> @Transactional -> TransactionInterceptor

org.springframework.transaction.interceptor.TransactionInterceptor

1
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

是方法在执行的时候,进行执行

Spring AOP @Aspectj

迭代器模式

java.lang.Iterable

  • Spring Environment 抽象
    • org.springframework.core.env.PropertySources
      • org.springframework.core.env.PropertySource

org.springframework.core.env.MutablePropertySources

1
2
3
public Iterator<PropertySource<?>> iterator() {
    return this.propertySourceList.iterator();
}

迭代器来就非常的简单了。

可以去迭代。

它可以让你的 这个东西去可以迭代。

调停者模式

Mediator pattern

img

猫的例子,

将一系列的组件给协调起来。

Spring MVC

  • DispatcherServlet (调节一下的组件)
    • HandlerMapping (List<HandlerMapping>)
    • HandlerAdapter (List<HandlerAdapter>)
    • HandlerExceptionResolver (List<HandlerExceptionResolver>)

先取出来 handler,再把这个对象进行相应的封装,处理它的映射。如果它有异常,那么那么那就会处理

它会调节者几个组件的动作。

备忘录模式

Memento pattern

就是回撤,java 的 回退

  • Spring Transaction -> JDBC 特性
    • #commit() #rollback() #savepoint
      1
      

savepoint s1

savepoint s2 commit(s2) || rollback(s2)

savepoint s3 commit(s3) || rollback(s3)

commit(s1)   rollback(s1)

org.springframework.transaction.interceptor.TransactionAspectSupport#commitTransactionAfterReturning

  • org.springframework.transaction.PlatformTransactionManager#commit
1
2
3
4
5
6
7
8
9
protected void commitTransactionAfterReturning(@Nullable TransactionAspectSupport.TransactionInfo txInfo) {
    if (txInfo != null && txInfo.getTransactionStatus() != null) {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
        }

        txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
    }
}

org.springframework.transaction.support.AbstractPlatformTransactionManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
    try {
        boolean beforeCompletionInvoked = false;

        try {
            boolean unexpectedRollback = false;
            this.prepareForCommit(status);
            this.triggerBeforeCommit(status);
            this.triggerBeforeCompletion(status);
            beforeCompletionInvoked = true;
            if (status.hasSavepoint()) {
                if (status.isDebug()) {
                    this.logger.debug("Releasing transaction savepoint");
                }

                unexpectedRollback = status.isGlobalRollbackOnly();
                // 保护点
                status.releaseHeldSavepoint();
            } else if (status.isNewTransaction()) {
                if (status.isDebug()) {
                    this.logger.debug("Initiating transaction commit");
                }

                unexpectedRollback = status.isGlobalRollbackOnly();
                this.doCommit(status);
            } else if (this.isFailEarlyOnGlobalRollbackOnly()) {
                unexpectedRollback = status.isGlobalRollbackOnly();
            }

            if (unexpectedRollback) {
                throw new UnexpectedRollbackException("Transaction silently rolled back because it has been marked as rollback-only");
            }
        } catch (UnexpectedRollbackException var17) {
            this.triggerAfterCompletion(status, 1);
            throw var17;
        } catch (TransactionException var18) {
            if (this.isRollbackOnCommitFailure()) {
                this.doRollbackOnCommitException(status, var18);
            } else {
                this.triggerAfterCompletion(status, 2);
            }

            throw var18;
        } catch (Error | RuntimeException var19) {
            if (!beforeCompletionInvoked) {
                this.triggerBeforeCompletion(status);
            }

            this.doRollbackOnCommitException(status, var19);
            throw var19;
        }

        try {
            this.triggerAfterCommit(status);
        } finally {
            this.triggerAfterCompletion(status, 0);
        }
    } finally {
        this.cleanupAfterCompletion(status);
    }

}

java.sql.Savepoint

有点像锁的概念。

观察者模式

  • Spring Event/Listener

    • ApplicationEvent / ApplicationListener
  • Spring LifeCycle

    • DefaultLifecycleProcessor

      • 生命周期回调所有的实现 LifeCycle Bean

      • 1
        2
        3
        4
        
        public void start() {
           startBeans(false);
           this.running = true;
        }
        

观察者模式和发布订阅者模式没有什么区别。

Demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class LifeCycleDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(MyLifeCycle.class);
        context.addApplicationListener(event -> {
            System.err.println("ContextStartedEvent...");
        });
        // context.register(......);
        // 启动 Spring 上下文
        context.refresh();

        // Spring 上下文也是 LifeCycle 的实现
        // 传播 start() 生命周期回调
        context.start();
        // 关闭 Spring 上下文
        context.close();
    }


    public static class MyLifeCycle implements Lifecycle{

        @Override
        public void start() {
            System.err.println("MyLifeCycle.start()....");
        }

        @Override
        public void stop() {
            System.err.println("MyLifeCycle.stop()...");
        }

        @Override
        public boolean isRunning() {
            return false;
        }
    }
}

使用场景

Lifecycle Spring 中使用较少,Spring Cloud 用的比较多。

Lifycycle 启动容器的时候,会显示的 #start() 传播生命周期 回调。

不断有事件传播,还有 LifeCycle 传播。

  • 先 lifeCycle
  • 再 事件传播

状态模式

A 状态 -》 B 状态 -》 C 状态

LifeCycle

  • Spring LifeCycle
    • DefaultLifecycleProcessor
      • 生命周期回调所有的实现 LifeCycle Bean
    • AbstractApplicationContext
      • 通过实现 LifeCycle 控制上下文的运行状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class LifeCycleDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(MyLifeCycle.class);

        context.addApplicationListener(event -> {
            if (event instanceof ContextStartedEvent)
                System.err.println("ContextStartedEvent...");
            if (event instanceof ContextStoppedEvent)
                System.err.println("ContextStoppedEvent...");
        });
        // context.register(......);
        // 启动 Spring 上下文
        context.refresh();

        System.err.println("在 start() 执行前:Spring 应用上下文是否运行:" + context.isRunning());

        // Spring 上下文也是 LifeCycle 的实现
        // 传播 start() 生命周期回调
        context.start();
        // 关闭 Spring 上下文

        System.err.println("在 start() 执行后:Spring 应用上下文是否运行:" + context.isRunning());

        context.stop();

        System.err.println("在 stop() 执行后:Spring 应用上下文是否运行:" + context.isRunning());

        // 传播 stop() 生命周期回调

        context.close();
    }


    public static class MyLifeCycle implements Lifecycle {

        @Override
        public void start() {
            System.err.println("MyLifeCycle.start()....");
        }

        @Override
        public void stop() {
            System.err.println("MyLifeCycle.stop()...");
        }

        @Override
        public boolean isRunning() {
            System.err.println("LifyCycle 状态....");
            return false;
        }
    }
}
Spring 的 LifeCycle 的接口有点鸡肋。。。
1
2
3
4
5
6
7
8
9
10
11
 start() 执行前:Spring 应用上下文是否运行:true
LifyCycle 状态....
MyLifeCycle.start()....
ContextStartedEvent...
 start() 执行后:Spring 应用上下文是否运行:true
LifyCycle 状态....
MyLifeCycle.stop()...
ContextStoppedEvent...
 stop() 执行后:Spring 应用上下文是否运行:false
00:49:13.566 [main] DEBUG org.springframework.context.support.DefaultLifecycleProcessor - Successfully stopped bean 'lifeCycleDemo.MyLifeCycle'
LifyCycle 状态....

DefaultLifeCycleProcessor.java 会根据你的状态来判断,来过滤。

这就是状态流转的控制方式!

策略模式

源码应看看版本。

org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean(java.lang.Class<T>, java.lang.Object...)

  • org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveBean
    • org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveNamedBean(org.springframework.core.ResolvableType, java.lang.Object[], boolean)
      • org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class<T>, java.lang.Object...)
        • org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Nullable
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
    NamedBeanHolder<T> namedBean = this.resolveNamedBean(requiredType, args, nonUniqueAsNull);
    if (namedBean != null) {
        return namedBean.getBeanInstance();
    } else {
        BeanFactory parent = this.getParentBeanFactory();
        if (parent instanceof DefaultListableBeanFactory) {
            return ((DefaultListableBeanFactory)parent).resolveBean(requiredType, args, nonUniqueAsNull);
        } else if (parent != null) {
            ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
            if (args != null) {
                return parentProvider.getObject(args);
            } else {
                return nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable();
            }
        } else {
            return null;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
   //..........

    if (candidateNames.length == 1) {
        String beanName = candidateNames[0];
        return new NamedBeanHolder(beanName, this.getBean(beanName, requiredType.toClass(), args));
    } else {
        // ...........
                if (this.containsSingleton(beanName) && args == null) {
                    Object beanInstance = this.getBean(beanName);
                    candidates.put(beanName, beanInstance instanceof NullBean ? null : beanInstance);
                } else {
                    candidates.put(beanName, this.getType(beanName));
                }
            }

          //...................

        return null;
    }
}
1
2
3
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) throws BeansException {
    return this.doGetBean(name, requiredType, args, false);
}
1
2
3
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
   // ,,,,,,,,,,,,,,
}
  • Spring InstantiationStrategy ->
    • CglibSubclassingInstantiationStrategy
    • SimpleInstantiationStrategy
  • Spring MVC
    • ContentNegotiationStrategy
      • 内容协商的策略
    • HeaderContentNegotiationStrategy
  • accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8

把请求头作为策略传递过来,告诉服务端,我这个客户端可以识别的格式。服务端根据我的格式进行返回。同一个 URL 可能对应不同的返回内容。

模板方法模式

  • Spring Core
    • AbstractApplicationContext#refreshBeanFactory()
    • AbstractRefreshableApplicationContext
    • GenericApplicationContext

很多抽象类都是模板方法模式。

策略是多种选一种,运行时自由切换。

而模板方法是不能切换,只能取其一。

访问者模式

Visitor pattern

img

A 、B 都是两个不同的对象

client 可以接收 visitor 的对象。

要加 visitorC 的时候,改动大

适合固定的模式,XML 的模式就是固定的 , HTML 的元素也是固定的。可列可举得。

  • Spring Core ASM 扩展
    • ClassVisitor
    • MethodVisitor
    • FieldVisitor

org.springframework.core.type.classreading.AbstractRecursiveAnnotationVisitor visit 模式

Recurisive 递归的,叫 注解的派生性 是 3.x 以后得某个版本才加上的。像

  • @Component
    • @Controller
      • @RestController

如果没有派生性很多东西都做不了。

1
2
3
4
5
6
@Component
public @interface MyComponent{
}
@MyComponent
public @interface MySubComponent{
}
  • @Component
    • @MyComponent
    • @MySubComponent
  • JSP 处理(Jasper)
  • XML 处理(XStream)
  • HTML 处理(Jsoup)
1
2
3
4
5
6
7
8
<html>
    <head>
        <title>
        </title>
    </head>
    <body>
    </body>
</html>

org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor @since 3.0.1

这个功能不太好,不太符合规矩,小版本修复 Bug

创造者模式

抽象工厂

  • Spring Core

    • FactoryBean

      • #getObject 方法
    • ObjectFactory

      这个接口 类似于 FacotoryBean 出现晚一点,返回对象的 SPI ,FacotryBean 可以指定响应的类型。

      • #getObject 方法

构造器模式

各种各样的 *builder

  • Spring Core
    • BeanDefinitionBuilder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class BeanDefinitionBuilderDemo {
    public static void main(String[] args) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Marker.class);
        builder.addConstructorArgValue("hello, world");
        /***
         * 创建 BeanDefinition
         */
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
        // 创建 BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 注册 BeanDefinition, 并以 “marker” Bean 名称
        beanFactory.registerBeanDefinition("marker", beanDefinition);
        // 或者 Marker bean
        System.out.println(beanFactory.getBean("marker", Marker.class));
    }

    /***
     * 方法定义
     * @return
     */
    @Bean
    public Object object(){
        return new Object();
    }

    /***
     * 类定义
     */
    @Component
    public static class MyComponent{
    }

    /***
     * 编码定义
     */
    @Data
    @AllArgsConstructor
    public static class Marker{
        private String name;
    }
}

BanDefinitioni Bean 的定义,一言而避之
  • 方法定义
  • 类定义
  • 编码定义
  • XML 定义
XML 定义
1
2
3
<bean id="clientService"
    factory-bean="serviceLocator"
    factory-method="createClientServiceInstance"/>

1
2
3
4
5
<beans>
    <bean id="marker" class="Marker">
        <constructor-arg ref="hello, World"/>
    </bean>
</beans>
静态方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Data
@AllArgsConstructor
public static class Marker{
    private String name;

    public static Marker createMarker(){
        return new Marker("Create static method");
    }
}
public static void createByStaticFacotry(){
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Marker.class);
    builder.setFactoryMethod("createMarker");
    /***
         * 创建 BeanDefinition
         */
    AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
    // 创建 BeanFactory
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    // 注册 BeanDefinition, 并以 “marker” Bean 名称
    beanFactory.registerBeanDefinition("marker", beanDefinition);
    // 或者 Marker bean
    System.out.println(beanFactory.getBean("marker", Marker.class));
}

工厂方法模式

  • Spring Core
    • BeanDefinitionBuilder#setFactoryMethod

XML 都可以用 java 代码进行实现。

Annotation 就是生成一下代码。

创建 Bean 的时候,都会去 #getMergedLocalBeanDefinition(String beanName) 都是有注解的处理器去创建。

原型模式

  • BeanDefinitionBuilder.setScope(BeanDefinition.SCOPE_PROTOTYPE)

单例模式

  • BeanDefinitionBuilder.setScope(BeanDefinition.SCOPE_SINGLETON)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
        createByfactory(BeanDefinition.SCOPE_SINGLETON);
        createByfactory(BeanDefinition.SCOPE_PROTOTYPE);
}

public static void createByfactory(String scope){
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Marker.class);
    builder.setScope(scope);
    builder.addConstructorArgValue("hello, world");
    /***
         * 创建 BeanDefinition
         */
    AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
    // 创建 BeanFactory
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    // 注册 BeanDefinition, 并以 “marker” Bean 名称
    beanFactory.registerBeanDefinition("marker", beanDefinition);
    // 或者 Marker bean
    System.out.println(beanFactory.getBean("marker", Marker.class) == beanFactory.getBean("marker", Marker.class));
}

学会利用 框架定义的常量!

BeanDefinition.SCOPE_SINGLETON

好的框架都会有常量的定义