MVC模式 |
Model:pojo、数据库交互(业务数据和业务逻辑)
View:Jsp(与用户交互页面) Controller:控制器(接收请求并决定调用哪个模块组件去处理请求,然后决定调用哪个视图(通过转发或重定向)来显示返回的数据)单例模式 |
public class Singleton { private static volatile Singleton sInstance = null; private Singleton () { } public static Singleton getInstance () { if (sInstance == null) { Synchronized(Singleton.class){ if (sInstance == null) { sInstance = new Singleton(); } } } return sInstance; }}
为什么需要用volatile修饰变量sInstance ?
因为sInstance = new Singleton();这行代码实际上做了以下工作:memory = allocate(); // 1:分配对象的内存空间ctorInstance(memory); // 2:初始化对象instance = memory; // 3:设置instance指向刚分配的内存地址
1、2、3指令可能会重排序为1、3、2,将导致外层判断出instance不为空,该线程接下来将访问instance引用的对象,而此对象事实上是一个还未初始化的对象。故需要加修饰,可以确保外层null检查要么看到的是null,要么看到的是一个构造完整的对象。
volatile可以保证有序性和可见性(即读操作在写操作之前)。工厂模式 |
适配器模式 |
- 使用场景
- 系统需要使用一些现有的类,而这些类的接口不符合系统的需要,甚至没有这些类的源代码
- 创建一个可以重复使用的类,用于和一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作
优点:将目标类和适配者类解耦,灵活性和扩展性都非常好,完全复合开闭原则。
缺点:一次最多只能适配一个适配者类,不能同时适配多个适配者。工厂方法
方式:实现FactoryBean接口。
原理: 实现了FactoryBean接口的bean是一类叫做factory的bean。其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该bean的getObject()方法,所以返回的不是factory这个bean,而是这个bean.getOjbect()方法的返回值。public SqlSessionFactory getObject() throws Exception { if (this.sqlSessionFactory == null) { afterPropertiesSet(); } return this.sqlSessionFactory; //返回的不是 SqlSessionFactoryBean 的实例,而是 SqlSessionFactoryBean.getObject() 的返回值}
适配器模式
方式:SpringMVC中的适配器HandlerAdatper。
原理:HandlerAdatper根据Handler规则执行不同的Handler。 过程: DispatcherServlet根据HandlerMapping返回的handler,向HandlerAdatper发起请求,处理Handler。HandlerAdapter根据规则找到对应的Handler并让其执行,执行完毕后Handler会向HandlerAdapter返回一个ModelAndView,最后由HandlerAdapter向DispatchServelet返回一个ModelAndView。 实现意义: HandlerAdatper使得Handler的扩展变得容易,只需要增加一个新的Handler和一个对应的HandlerAdapter即可。因此Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类,让适配器代替controller执行相应的方法。这样在扩展Controller时,只需要增加一个适配器类就完成了SpringMVC的扩展了。- 不同类型的Handle
- 继承Controller方式所使用的适配器:SimpleControllerHandlerAdapter
- HTTP请求处理器适配器:HttpRequestHandlerAdapter
- 注解方式(@Controller)的处理器适配器:RequestMappingHandlerAdapter