由工厂类根据传入的参数,动态决定应该创建哪一个产品类的对象,实现“创建与使用相分离”。
简单工厂模式只有一个工厂类,使用静态方法来创建产品对象。
- 单一工厂类负责所有产品的创建,职责过重,违背高聚合原则;
- 增加新产品必须修改工厂方法逻辑,违背开闭原则
Spring读取xml配置文件,将
这里的BeanFactory就是一个简单工厂,特点是延迟注入(使用到某个bean时才会创建)。
而ApplicationContext就是容器启动时创建所有bean,并扩展了除依赖注入外的其他功能。
在简单工厂基础上,抽象出一个工厂接口,各子工厂类实现创建产品对象的抽象方法。
Spring的FactoryBean就是一个定义了getObject方法的工厂接口。
通过getBean获取实现了FactoryBean接口的bean时,会自动调用其getObject方法,所以返回的不是该类的实例,而是其getObject方法的返回值。
典型例子就是Spring和MyBatis的结合:
这个class因为实现了FactoryBean接口,注入的bean就是SqlSessionFactoryBean.getObject()
单例模式系统中有些对象只需要一个即可,如线程池、缓存、日志对象、设备驱动等。
优点:
1.对于频繁使用的对象,节省重复创建的时间开销
2.由于new *** 作减少,系统内存的使用频率降低,减轻GC压力
Spring中bean的默认作用域就是singleton(单例),prototype则是每次创建新实例。
Spring通过维护ConcurrentHashMap单例注册表的方式实现单例模式。
synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); }代理模式
给目标对象提供一个代理,以控制对该对象的访问。
优点:
1.代理作为一个中介,可保护目标对象
2.代理可以扩展目标对象的功能
静态代理:代理目标固定,在程序执行前就代理类的.class就存在了
动态代理:通过反射机制在程序运行期动态地为目标创建代理对象
Spring AOP就是基于动态代理,将那些与业务无关但又被业务模块调用的共同逻辑(如事物处理、日志管理、权限控制等)封装起来,提高代码复用率。
对于实现了接口的类,Spring AOP通过JDK Proxy创建代理对象;
对于没有实现接口的类,Spring AOP使用CgLib生产一个目标对象的子类作为代理。
Spring AOP 属于运行时增强,而 AspectJ 是编译时增强;Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码 *** 作(Bytecode Manipulation)。若切面较多,选择后者速度优势明显。
模版方法模式定义一个 *** 作的骨架,并将部分步骤延迟到子类中实现,从而达成不改变结构即可重定义特点步骤的效果。
public abstract class Template { //模板方法 public final void TemplateMethod(){ PrimitiveOperation1(); PrimitiveOperation2(); PrimitiveOperation3(); } protected void PrimitiveOperation1(){ // 当前类实现 } // 由子类实现的方法 protected abstract void PrimitiveOperation2(); protected abstract void PrimitiveOperation3(); }
Spring的jdbcTemplate就使用了模版方法模式,但不是通过继承来实现的,而是Callback 模式与模板方法模式配合,既达到了代码复用的效果,同时增加了灵活性。
观察者模式适用场景:对象之间具有依赖关系,当一个对象改变,其依赖的对象也会做出反应。
Spring事件驱动模型就是观察者模式的一个经典应用。
事件:ApplicationEvent,是一个抽象类,继承了java.util.EventObject并实现了 java.io.Serializable接口。
事件监听者:ApplicationListener,是一个接口,只定义了onApplicationEvent方法来处理ApplicationEvent。
事件发布者:ApplicationEventPublisher,是一个接口,定义了publishEvent方法,在AbstractApplicationContext中实现,通过ApplicationEventMulticaster将事件广播出去。
将一个接口转化为另一个期望的接口,使接口不兼容的类可以一起工作。
目标接口:业务系统期望的接口;
适配者:被适配的组件类;
适配器:通过引用或继承适配者对象,使客户可按目标接口的格式访问适配者。
Spring MVC的请求处理器有多种实现方式(继承Controller的、基于注解方式的、HttpRequestHandler),普通情况下想要调用需要if else判断instance of,再编写调用逻辑。一旦添加新的处理器,就需要修改代码,不符合开闭原则。
于是Spring定义了一个处理器适配器接口:
public interface HandlerAdapter { // 用于判断当前HandlerAdapter是否能够处理当前请求 boolean supports(Object handler); // 如果当前HandlerAdapter能够用于适配当前请求,那么就会处理当前请求中 // 诸如参数和返回值等信息,以便能够直接委托给具体的Handler处理 ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; // 获取当前请求的最后更改时间,主要用于供给浏览器判断当前请求是否修改过, // 从而判断是否可以直接使用之前缓存的结果 long getLastModified(HttpServletRequest request, Object handler); }
DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。根据Handler获取其对应的HandlerAdapter适配器子类(遍历所有适配器的supports方法),最后调用这个适配器子类的handle方法处理请求返回ModelAndView。
这样,当需要新增处理器类时,只需手动实现一个对应的适配器子类即可,无需变动已有代码。
动态地给对象附加一些额外的属性或行为,相比继承更灵活。
Spring中名称带Wrapper或Decorator的类。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)