Spring设计模式探幽(1)

设计伊始

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

  • 小结

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

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

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

区别

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值