Spring设计模式探幽(1)

来源:互联网 发布:数据挖掘的特点 编辑:程序博客网 时间:2024/06/05 05:20

设计伊始

  Spring 是为解决企业级应用开发的复杂性而设计,她可以做很多事。但归根到底支撑Spring的仅仅是少许的基本理念,而所有地这些的基本理念都能可以追溯到一个最根本的使命:简化开发。这是一个郑重的承诺,其实许多框架都声称在某些方面做了简化。    而Spring则立志于全方面的简化Java开发。对此,她主要采取了4个关键策略:        1,基于POJO的轻量级和最小侵入性编程;        2,通过依赖注入和面向接口松耦合;        3,基于切面和惯性进行声明式编程;        4,通过切面和模板减少样板式代码;    而他主要是通过:面向Bean、依赖注入以及面向切面这三种方式来达成的。    而设计如此精妙的spring,其中肯定是有许多设计模式的,下面我们就通过阅读分析spring的源码来感受spring的密码。     贴一个spring源码下载地址,下载托管在github了。     https://github.com/spring-projects/spring-framework/tags     我下的是spring3.2.5 release

常见的九种设计模式

分别是:简单工厂、工厂方法、单例模式、适配器模式、包装器模式、代理模式、观察者模式、策略模式、模板方法模式

1.工厂模式

org.springframework.beans.factory 这里是定义spring IOC容器接口的包,在这个包里有我们熟悉的BeanFactory package org.springframework.beans.factory;  public interface BeanFactory {      /**      *这里是对FactoryBean的转义定义,如果使用bean的名字检索FactoryBean,得到的是工厂生成的对象,         *如果需要得到工厂本身,需要转义。For example, if the bean named      * <code>myJndiObject</code> is a FactoryBean, getting <code>&myJndiObject</code>      * will return the factory       */               String FACTORY_BEAN_PREFIX = "&";         /**      *这里根据bean的名字,在IOC容器中得到bean实例,这个IOC容器就是一个大的抽象工厂。      */         Object getBean(String name) throws BeansException;         /**      *这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果      *根据名字取得的bean实例的Class类型和需要的不同的话。      */         Object getBean(String name, Class requiredType) throws BeansException;         /**     *这里提供对bean的检索,看看是否在IOC容器有这个名字的bean     */         boolean containsBean(String name);         /**      *这里根据bean名字得到bean实例,并同时判断这个bean是不是单例      */        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;         /**      *这里得到bean实例的Class类型       */      Class getType(String name) throws NoSuchBeanDefinitionException;         /**      *这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来      */         String[] getAliases(String name);     }  
  1. spring中BeanFactory和ApplicationContext的创建中都用到了典型的静态工厂模式。Bean 的创建采用了的工厂模式,他的顶级接口是 BeanFactory。BeanFactory 有三个子接口:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactor。这三个接口主要是为了区分在 Spring 内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。这三个子接口集成了顶级接口并对BeanFactory的功能进行了增强,称为二级接口;ConfigurableBeanFactory对二级接口HierarchicalBeanFactory进行了再次增强,它还继承了另一个外来的接口SingletonBeanRegistry,可以被称为三级接口;ConfigurableListableBeanFactory是一个更强大的接口,继承了上述的所有接口,称为四级接口。其余的为抽象类,实现了Spring Bean四级接口所定义的所有功能。
    spring

一般来说采用BeanFactory的子接口ApplicationContext来创建BeanFactory的实例。ApplicationContext通常使用如下两个实现类:
FileSystemXmlApplicationContext:以基于文件系统的XML配置文件创建ApplicationContext实例。
ClassPathXmlApplicationContext:以类加载路径下的XML配置文件创建的ApplicationContext实例

public void testAC() {        //1.在这里ApplicationContext接口继承了ListableBeanFactory, HierarchicalBeanFactory等二级接口        ApplicationContext ac = new ClassPathXmlApplicationContext("cn/xyf/a_hello/applicationContext.xml");        //2.从容器获取Bean        User user = (User) ac.getBean("user");        System.out.println(user);    }
  • 在spring中,BeanFactory拥有类似的功能,它负责实例化、配置和管理对象。我们一般用的BeanFactory的实现类ApplicationContext,这个类会自动解析我们配置的applicationContext.xml,然后调用实现后的getBean方法然后根据我们配置的bean来new对象,将new好的对象放进一个容器中,键就是我们bean的id,值就是new的对象。

  • 在这里给出简单工厂模式的实现

//简单工厂模式package cn.xyf.factory;/** * @author Dale *  封装一个雷峰类 */public class LeiFeng {    //扫地    public void sweep(){        System.out.println("扫地");    }    //洗衣    public void wash(){        System.out.println("洗衣");    }    //买米    public void buyRice(){        System.out.println("买米");    }}//大学生子类class UnderGraduate extends LeiFeng{}//社区志愿者子类class Volunteer extends LeiFeng{}package cn.xyf.factory;/** * @author Dale * 简单工厂模式 */public class SimpleFactory {    //静态方法创建雷锋对象    public static LeiFeng createLeiFeng(String type){        LeiFeng result = null;        switch(type){            case "UnderGraduate":                result = new UnderGraduate();                break;            case "UnderGrate":                result = new Volunteer();                break;        }        return result;    }}package cn.xyf.factory;/** * @author Dale * java 工厂模式 */public class Client {    public static void main(String[] args) {        //1.简单工厂模式          LeiFeng s1 = SimpleFactory.createLeiFeng("UnderGraduate");        LeiFeng s2 = SimpleFactory.createLeiFeng("UnderGrate");        s1.wash();        s2.buyRice();}
  • 在这里补充一下简单工厂、工厂、抽象工厂三者的区别

    1. 简单工厂
      简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
      不修改代码的话,是无法扩展的。

    2. 工厂方法
      工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
      在同一等级结构中,支持增加任意产品。

    3. 抽象工厂
      抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。
      应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。

  • 小结

★工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。

★使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。

★工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。

区别

简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)

工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 甘肃人力资源保障厅 广州市人力资源和社会保障局 人力社会保障局社保网 深圳市人力资源社会保障局 贵阳人力资源 深圳市人力资源和社会保障局 重庆市人力资源和社会保障局 青岛市人力资源和社会保障局 罗德岛人力资源部 河南省人力资源和社会保障厅 重庆人力资源和社保局网 潍坊市人力资源和社会保障局 台山人才人力资源网 河南省人力资源社会保障厅 重庆市人力资源社会保障局 潍坊市人力资源社会保障局 广州市人力资源保障局 深圳市人力资源保障局 北京市人力资源和社会保障局 重庆市人力资源社会保障网 成都市人力资源和社会保障局 北京市人力资源社会保障局 吴江人力资源 贵阳人力资源社会保障网 重庆市人力资源和社会保障网 漯河市人力资源和社会保障局 成都市人力资源社会保障局 罗德岛人力资源 漯河市人力资源社会保障局 青岛市人力资源社会保障局 淄博人力资源网 济南市人力资源和社会保障局 胶州人力资源网 重庆市人力资源保障局 新疆人力资源和社会保障厅 人力资源服务公司 广东人力资源 广东省人力资源 人力资源公司 人力资源服务 人力资源会计