Spring必知必会,底层都使用了哪些设计模式?
Spring用到的设计模式
1
代理模式:最常见的 AOP 的实现方式就是通过代理来实现,Spring主要是使用 JDK 动态代理和 CGLIB 代理。
其中JDK代理实现代码如下所示:
public class ProxyHandler implements InvocationHandler {
Object target;
public ProxyHandler(Object target) {
this.target=target;
}
public void before(String param) throws Throwable {
if(!param.equals("magicalwolf"))
throw new IllegalArgumentException();
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
before((String)args[0]);
return method.invoke(target, args);
}
}
public class Main {
public static void main(String[] args) {
Subject target=new RealSubject();
Subject proxy=(Subject)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new ProxyHandler(target));
proxy.request("magicalwolf");
proxy.request("hello");
}
}
CGLIB代理实现如下:
public class RequestInterceptor implements MethodInterceptor {
public void before(String param) throws Throwable {
if(!param.equals("hello"))
throw new IllegalArgumentException();
}
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
before((String)args[0]);
return proxy.invokeSuper(obj, args);//调用父类的方法
}
}
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer(); //字节码增强器
enhancer.setSuperclass(RealSubject.class); //代理类
enhancer.setCallback(new RequestInterceptor());//回调方法
Subject proxy = (Subject) enhancer.create();
proxy.request("hello");
}
}
2
模版模式:定义了一个在操作中的算法框架,而将一些具体步骤延迟到子类中,使子类看可以在不改变算法结构下即可重新定义该算法的某些特定步骤。
主要是一些对数据库操作的类用到,比如 JdbcTemplate、JpaTemplate,因为查询数据库的建立连接、执行查询、关闭连接几个过程,非常适用于模板方法。
//提交事务
protected abstract void doCommit(DefaultTransactionStatus status);
//回滚事务
protected abstract void doRollback(DefaultTransactionStatus status);
//开始事务
protected abstract void doBegin(Object transaction, TransactionDefinition definition)
//获取当前的事务对象
protected abstract Object doGetTransaction()
Spring框架启动也遵循如准备启动上下文,初始化BeanFactory、BeanFactory对象的前置处理与注册,消息发送器初始化,发送应用启动消息等等特定的特定启动流程,将BeanFactory的初始化和刷新留在了具体的应用实现类去实现。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
public void refresh() throws BeansException, IllegalStateException {
prepareRefresh();
//子类实现初始化BeanFactory对象
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
// 两个抽象方法
public abstract ConfigurableListableBeanFactory getBeanFactory()
throws IllegalStateException;
protected abstract void refreshBeanFactory()
throws BeansException, IllegalStateException;
}
3
工厂模式:定义了用于创建对象的接口,让子类决定要创建哪个类的实例化,可以促进组件或类之间的松耦合,通过使用接口而不是将特定的类绑定到应用程序代码中。
Spring框架使用工厂模式实现了 BeanFactory 和 ApplicationContext 接口,基于工厂模式为Spring应用程序创建Bean,并管理着每一个Bean的生命周期。如BeanFactory实例中的doGetBean方法可以根据使用者传入的名字,类型,参数等生成对象并返回。
public class StaticListableBeanFactory implements ListableBeanFactory {
private final Map<String, Object> beans;
protected <T> T doGetBean(
String name, Class<T> requiredType, Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object beanInstance;
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
}
4
单例模式:保证了一个类仅有的一个实例,并提供了一个访问它的全局访问点,提供控制器对关键类的访问。
单例模式如DB的连接类或Hibernate中的SessionFactory类,节省了大量的内存,Spring框架中的Bean对象默认都是为单例,在Bean对象注册器实例上使用了Map来管理Bean对象,每次获取到的对象是从该单例容器中取出来的。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
}
5
责任链可以避免发送者与请求者耦合在一起,让多个对象都有可能接收到请求,将这些对象连接成一条链,并且沿着这条链路传递请求,直到有对象处理为止。
Spring中的Filter实现了责任链模式,管理者所有的Filter的顺序执行,可以对同一种对象资源实现不同业务场景的处理,达到业务解耦。详情可参考以下链接。
public final class ApplicationFilterChain implements FilterChain {
private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
private int pos = 0;
private int n = 0;
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
internalDoFilter(request,response);
}
private void internalDoFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = filterConfig.getFilter();
filter.doFilter(request, response, this);
}
}
}
6
观察者模式: 定义了对象之间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都能得到通知并自动更新。
在Spring框架中,观察者用于实现ApplicationContext的事件处理功能,为开发者提供了ApplicationEvent和ApplicationLIstneter接口来启用事件处理,任何Bean实现了SpringListner接口都会收到ApplicationEvent作为事件发布者推送的消息。更多详情可参考以下链接。
public class PublishService {
private ApplicationContext applicationContext;
public void publishEvent() {
applicationContext.publishEvent(new TestSuccessEvent(this));
}
}
public class ListenService {
(TestSuccessEvent.class)
public void test() {
....
}
}
public class AsyncEventConfig {
"applicationEventMulticaster") (name =
public ApplicationEventMulticaster simpleApplicationEventMulticaster() {
SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster();
eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
return eventMulticaster;
}
}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
.....
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
.....
}
7
适配器模式:将一个类的接口转换成希望的另外一个接口,Spring框架使用适配器模式实现了很多功能,常见的适配器模式的类有 配置适配器RequestMappinghandlerAdapter完成了从请求到方法的映射,返回值到对应的视图或页面的适配转换。
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
ContentNegotiationManager contentNegotiationManager,
FormattingConversionService conversionService,
Validator validator) {
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
.....
return adapter;
}
}
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
implements BeanFactoryAware, InitializingBean {
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
}
8
建造者模式: 可以一步步构建一个复杂的对象,最终将返回完整的对象,对象创建的逻辑和过程是通用的,使用它来创建相同的类型的不同具体实现,隐藏了调用方调用代码时构建对象的细节。
Spring框架中有一些功能实现了建造者模式如EmbeddedDatabaseBuilder、BeanDefinitionBuilder、MockMvcWebClientBuilder等。
public class EmbeddedDatabaseBuilder {
......
public EmbeddedDatabaseBuilder setName(String databaseName) {
this.databaseFactory.setDatabaseName(databaseName);
return this;
}
public EmbeddedDatabaseBuilder setType(EmbeddedDatabaseType databaseType) {
this.databaseFactory.setDatabaseType(databaseType);
return this;
}
public EmbeddedDatabaseBuilder setDataSourceFactory(DataSourceFactory dataSourceFactory) {
Assert.notNull(dataSourceFactory, "DataSourceFactory is required");
this.databaseFactory.setDataSourceFactory(dataSourceFactory);
return this;
}
......
}
IOC和AOP的理解
IOC 叫做控制反转。指的是通过Spring来管理对象的创建、配置和生命周期,这样相当于把控制权交给了Spring,不需要人工来管理对象之间复杂的依赖关系,这样做的好处就是解耦。
在Spring里面,主要提供了 BeanFactory 和 ApplicationContext 两种 IOC 容器。
AOP 叫做面向切面编程。是一个编程范式,目的就是提高代码的模块性。
Spring AOP 基于动态代理的方式实现,如果是实现了接口的话就会使用 JDK 动态代理,反之则使用 CGLIB 代理。
Spring中, AOP 的应用主要体现在事务、日志、异常处理等方面,通过在代码的前后做一些增强处理,可以实现对业务逻辑的隔离,提高代码的模块化能力,同时也是解耦。Spring主要提供了 Aspect 切面、JoinPoint 连接点、PointCut 切入点、Advice 增强等实现方式。
几种代理方式的实现方式与区别
Spring必知必会上篇完,下篇内容预告:
Spring AOP 和 AspectJ AOP 有什么区别?
5.Spring框架的主要模块
Bean的生命周期
……
……
更多干货请点击关注
▼