深入解析spring中用到的九種設計模式
第一種:單例模式
spring容器中的bean默認是單例的,一般情況下用戶不會自己創建Bean,而是交給容器去管理,spring不是通過私有化構造函數進行的單例模式控制。Spring框架對單例的支持是採用單例註冊表的方式進行實現的。
第二種:簡單工廠
簡單又叫做靜態工廠方法(StaticFactory Method)模式,
傳入對應的類型就可構建對應的對象
第三種:工廠方法
spring常用的創建方式有以下四種:
-
setter 方法
-
構造函數
-
靜態工廠
-
實例工廠
<bean id="bmwCar" class="com.home.factoryMethod.Car" factory-method="getCar">
</bean>
第四種:裝飾者模式
第五種:代理模式
Spring AOP 功能的實現。
第六種:適配器模式
在Spring MVC中,DispatcherServlet
調用 HandlerMapping
,解析請求對應的 Handler
。解析到對應的 `Handler後。不同的handler並無任何聯繫,爲了統一處理,使用HandlerAdapter進行統一的處理。
Spring AOP 的通知(Advice)使用到了適配器模式,Advice 常用的類型有:BeforeAdvice
、AfterAdvice
、AfterReturningAdvice等等。每個類型Advice都有對應的攔截器:
AdviceInterceptor。Spring的通知要通過對應的AdviceAdapter,適配成
MethodInterceptor`接口(方法攔截器)類型的對象
第七種:策略
spring中在實例化對象的時候用到Strategy模式
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CUcP6eAK-1579404043633)(C:\Users\Administrator\Desktop\TIM截圖20200119105317.png)]
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
//如果有需要覆蓋或動態替換的方法,則使用cglib進行動態代理,
//應爲可以在創建代理的同時,將動態方法織入類中
//如果沒有,直接用反射就可以進行實例化
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException...
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
第八種:模板方法
模板方法模式是一種行爲設計模式,它定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。 模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟的實現方式。
第九種:觀察者
定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。
spring中Observer模式常用的地方是listener的實現。如ApplicationListener。
1、定義一個事件
public class MyEvent extends ApplicationEvent {
public MyEvent(Object source) {
super(source);
System.out.println("發送了郵件");
}
}
2、定義事件監聽
@Component
public class MyReceive {
@EventListener
public void receive(MyEvent event){
System.out.println("接收到"+event);
}
}
3、發佈事件
@RestController
public class MailSender implements ApplicationContextAware {
ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
@RequestMapping("/mtest")
public String sendMail(){
//創建時間
MyEvent myEvent = new MyEvent(applicationContext);
System.out.println("準備發-----");
//發佈事件
applicationContext.publishEvent(myEvent);
return "success";
}
}