建造者模式
真实场景1:Spring-Cloud-Gateway中Route的建造者模式实现,一个有点复杂且完善的实现,但是对于构建Route来说非常方便
public class RouteLocatorBuilder {
private ConfigurableApplicationContext context;
public RouteLocatorBuilder(ConfigurableApplicationContext context) {
this.context = context;
}
/**
* Creates a new {@link Builder}.
* @return a new {@link Builder}.
*/
public Builder routes() {
return new Builder(context);
}
/**
* A class that can be used to construct routes and return a {@link RouteLocator}.
*/
public static class Builder {
private List<Route.AsyncBuilder> routes = new ArrayList<>();
private ConfigurableApplicationContext context;
public Builder(ConfigurableApplicationContext context) {
this.context = context;
}
/**
* Creates a new {@link Route}.
* @param id the unique id for the route
* @param fn a function which takes in a {@link PredicateSpec} and returns a
* {@link Route.AsyncBuilder}
* @return a {@link Builder}
*/
public Builder route(String id, Function<PredicateSpec, Route.AsyncBuilder> fn) {
Route.AsyncBuilder routeBuilder = fn.apply(new RouteSpec(this).id(id));
add(routeBuilder);
return this;
}
/**
* Creates a new {@link Route}.
* @param fn a function which takes in a {@link PredicateSpec} and returns a
* {@link Route.AsyncBuilder}
* @return a {@link Builder}
*/
public Builder route(Function<PredicateSpec, Route.AsyncBuilder> fn) {
Route.AsyncBuilder routeBuilder = fn.apply(new RouteSpec(this).randomId());
add(routeBuilder);
return this;
}
/**
* Builds and returns a {@link RouteLocator}.
* @return a {@link RouteLocator}
*/
public RouteLocator build() {
return () -> Flux.fromIterable(this.routes)
.map(routeBuilder -> routeBuilder.build());
}
ConfigurableApplicationContext getContext() {
return context;
}
void add(Route.AsyncBuilder route) {
routes.add(route);
}
}
public static class RouteSpec {
private final Route.AsyncBuilder routeBuilder = Route.async();
private final Builder builder;
RouteSpec(Builder builder) {
this.builder = builder;
}
public PredicateSpec id(String id) {
this.routeBuilder.id(id);
return predicateBuilder();
}
public PredicateSpec randomId() {
return id(UUID.randomUUID().toString());
}
private PredicateSpec predicateBuilder() {
return new PredicateSpec(this.routeBuilder, this.builder);
}
}
}
public class Route implements Ordered {
private final String id;
private final URI uri;
private final int order;
private final AsyncPredicate<ServerWebExchange> predicate;
private final List<GatewayFilter> gatewayFilters;
private final Map<String, Object> metadata;
@Deprecated
private Route(String id, URI uri, int order,
AsyncPredicate<ServerWebExchange> predicate,
List<GatewayFilter> gatewayFilters) {
this(id, uri, order, predicate, gatewayFilters, new HashMap<>());
}
private Route(String id, URI uri, int order,
AsyncPredicate<ServerWebExchange> predicate,
List<GatewayFilter> gatewayFilters, Map<String, Object> metadata) {
this.id = id;
this.uri = uri;
this.order = order;
this.predicate = predicate;
this.gatewayFilters = gatewayFilters;
this.metadata = metadata;
}
public static Builder builder() {
return new Builder();
}
public static Builder builder(RouteDefinition routeDefinition) {
// @formatter:off
return new Builder().id(routeDefinition.getId())
.uri(routeDefinition.getUri())
.order(routeDefinition.getOrder())
.metadata(routeDefinition.getMetadata());
// @formatter:on
}
public static AsyncBuilder async() {
return new AsyncBuilder();
}
public static AsyncBuilder async(RouteDefinition routeDefinition) {
// @formatter:off
return new AsyncBuilder().id(routeDefinition.getId())
.uri(routeDefinition.getUri())
.order(routeDefinition.getOrder())
.metadata(routeDefinition.getMetadata());
// @formatter:on
}
public String getId() {
return this.id;
}
public URI getUri() {
return this.uri;
}
public int getOrder() {
return order;
}
public AsyncPredicate<ServerWebExchange> getPredicate() {
return this.predicate;
}
public List<GatewayFilter> getFilters() {
return Collections.unmodifiableList(this.gatewayFilters);
}
public Map<String, Object> getMetadata() {
return Collections.unmodifiableMap(metadata);
}
public abstract static class AbstractBuilder<B extends AbstractBuilder<B>> {
protected String id;
protected URI uri;
protected int order = 0;
protected List<GatewayFilter> gatewayFilters = new ArrayList<>();
protected Map<String, Object> metadata = new HashMap<>();
protected AbstractBuilder() {
}
protected abstract B getThis();
public B id(String id) {
this.id = id;
return getThis();
}
public String getId() {
return id;
}
public B order(int order) {
this.order = order;
return getThis();
}
public B uri(String uri) {
return uri(URI.create(uri));
}
public B uri(URI uri) {
this.uri = uri;
String scheme = this.uri.getScheme();
Assert.hasText(scheme, "The parameter [" + this.uri
+ "] format is incorrect, scheme can not be empty");
if (this.uri.getPort() < 0 && scheme.startsWith("http")) {
// default known http ports
int port = this.uri.getScheme().equals("https") ? 443 : 80;
this.uri = UriComponentsBuilder.fromUri(this.uri).port(port).build(false)
.toUri();
}
return getThis();
}
public B replaceMetadata(Map<String, Object> metadata) {
this.metadata = metadata;
return getThis();
}
public B metadata(Map<String, Object> metadata) {
this.metadata.putAll(metadata);
return getThis();
}
public B metadata(String key, Object value) {
this.metadata.put(key, value);
return getThis();
}
public abstract AsyncPredicate<ServerWebExchange> getPredicate();
public B replaceFilters(List<GatewayFilter> gatewayFilters) {
this.gatewayFilters = gatewayFilters;
return getThis();
}
public B filter(GatewayFilter gatewayFilter) {
this.gatewayFilters.add(gatewayFilter);
return getThis();
}
public B filters(Collection<GatewayFilter> gatewayFilters) {
this.gatewayFilters.addAll(gatewayFilters);
return getThis();
}
public B filters(GatewayFilter... gatewayFilters) {
return filters(Arrays.asList(gatewayFilters));
}
public Route build() {
Assert.notNull(this.id, "id can not be null");
Assert.notNull(this.uri, "uri can not be null");
AsyncPredicate<ServerWebExchange> predicate = getPredicate();
Assert.notNull(predicate, "predicate can not be null");
return new Route(this.id, this.uri, this.order, predicate,
this.gatewayFilters, this.metadata);
}
}
public static class AsyncBuilder extends AbstractBuilder<AsyncBuilder> {
protected AsyncPredicate<ServerWebExchange> predicate;
@Override
protected AsyncBuilder getThis() {
return this;
}
@Override
public AsyncPredicate<ServerWebExchange> getPredicate() {
return this.predicate;
}
public AsyncBuilder predicate(Predicate<ServerWebExchange> predicate) {
return asyncPredicate(toAsyncPredicate(predicate));
}
public AsyncBuilder asyncPredicate(AsyncPredicate<ServerWebExchange> predicate) {
this.predicate = predicate;
return this;
}
public AsyncBuilder and(AsyncPredicate<ServerWebExchange> predicate) {
Assert.notNull(this.predicate, "can not call and() on null predicate");
this.predicate = this.predicate.and(predicate);
return this;
}
public AsyncBuilder or(AsyncPredicate<ServerWebExchange> predicate) {
Assert.notNull(this.predicate, "can not call or() on null predicate");
this.predicate = this.predicate.or(predicate);
return this;
}
public AsyncBuilder negate() {
Assert.notNull(this.predicate, "can not call negate() on null predicate");
this.predicate = this.predicate.negate();
return this;
}
}
public static class Builder extends AbstractBuilder<Builder> {
protected Predicate<ServerWebExchange> predicate;
@Override
protected Builder getThis() {
return this;
}
@Override
public AsyncPredicate<ServerWebExchange> getPredicate() {
return ServerWebExchangeUtils.toAsyncPredicate(this.predicate);
}
public Builder and(Predicate<ServerWebExchange> predicate) {
Assert.notNull(this.predicate, "can not call and() on null predicate");
this.predicate = this.predicate.and(predicate);
return this;
}
public Builder or(Predicate<ServerWebExchange> predicate) {
Assert.notNull(this.predicate, "can not call or() on null predicate");
this.predicate = this.predicate.or(predicate);
return this;
}
public Builder negate() {
Assert.notNull(this.predicate, "can not call negate() on null predicate");
this.predicate = this.predicate.negate();
return this;
}
}
}
使用方式:
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.host("**.abc.org").and().path("/image/png")
.filters(f ->
f.addResponseHeader("X-TestHeader", "foobar"))
.uri("http://httpbin.org:80")
)
.build();
}
抽象工厂模式
真实场景1:Spring-Cloud-Gateway中,GatewayFilterFactory的派生类能够生产出不同的GatewayFilter,以满足不同的需求,比如AddRequestHeaderGatewayFilterFactory:为请求Header添加指定值,AddResponseHeaderGatewayFilterFactory:为响应Header添加指定值。抽象工厂其实是注重产品之间的关系,抽象出公共部分
public interface GatewayFilterFactory<C> extends ShortcutConfigurable, Configurable<C> {
/**
* Name key.
*/
String NAME_KEY = "name";
/**
* Value key.
*/
String VALUE_KEY = "value";
// useful for javadsl
default GatewayFilter apply(String routeId, Consumer<C> consumer) {
C config = newConfig();
consumer.accept(config);
return apply(routeId, config);
}
default GatewayFilter apply(Consumer<C> consumer) {
C config = newConfig();
consumer.accept(config);
return apply(config);
}
default Class<C> getConfigClass() {
throw new UnsupportedOperationException("getConfigClass() not implemented");
}
@Override
default C newConfig() {
throw new UnsupportedOperationException("newConfig() not implemented");
}
GatewayFilter apply(C config);
default GatewayFilter apply(String routeId, C config) {
if (config instanceof HasRouteId) {
HasRouteId hasRouteId = (HasRouteId) config;
hasRouteId.setRouteId(routeId);
}
return apply(config);
}
default String name() {
// TODO: deal with proxys
return NameUtils.normalizeFilterFactoryName(getClass());
}
@Deprecated
default ServerHttpRequest.Builder mutate(ServerHttpRequest request) {
return request.mutate();
}
}
...中间的其他抽象工厂就省略不展示了
public class AddRequestHeaderGatewayFilterFactory
extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
ServerHttpRequest request = exchange.getRequest().mutate()
.header(config.getName(), value).build();
return chain.filter(exchange.mutate().request(request).build());
}
@Override
public String toString() {
return filterToStringCreator(AddRequestHeaderGatewayFilterFactory.this)
.append(config.getName(), config.getValue()).toString();
}
};
}
}
迭代器模式
真实场景:java中的集合类,下面以ArrayList为例
public interface Iterable<T> {
Iterator<T> iterator();
//该方法可以使用for(T element : collection)语法糖
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
//获取Iterator
public Iterator<E> iterator() {
return new Itr();
}
//获取ListIterator
public ListIterator<E> listIterator() {
return listIterator(0);
}
//实现标准Iterator接口
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
* Index of element returned by most recent call to next or
* previous. Reset to -1 if this element is deleted by a call
* to remove.
*/
int lastRet = -1;
/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size();
}
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
//实现ListIterator,增加更多list相关方法,可以访问前驱节点,后驱节点
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public E previous() {
checkForComodification();
try {
int i = cursor - 1;
E previous = get(i);
lastRet = cursor = i;
return previous;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor-1;
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.set(lastRet, e);
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
AbstractList.this.add(i, e);
lastRet = -1;
cursor = i + 1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
}