---

layout: post
title: "Spring协调作用域不同步的bean"
category: Reading Notes

tags: ["读书", "Spring"]

{% include JB/setup %}

协调作用域不同步的Bean

<bean id="steelAxe" class="..." scope="prototype"/>

<bean id="chinese" class="...">
    <lookup-method name="getAxe" bean="steelAxe"/>
</bean>

chinese是singleton;steelAxe是prototype

程序多次引用chinese的时候,实际引用的是同一个实例

这样会造成steelAxe也每次都是同一个实例,违反了其prototype的scope

解决方法

public class SteelAxe implements Axe
{
    public SteelAxe()
    {
        System.out.println("Spring实例化依赖Bean:SteelAxe实例...");
    }

    public String chop()
    {
        return "钢斧砍柴!";
    }
}

public abstract class Chinese implements Person
{
    public Chinese()
    {
        System.out.println("Spring实例化主调bean:Chinese实例...");
    }

    // 交由Spring来实现
    public abstract Axe getAxe();

    public void useAxe()
    {
        System.out.println("正在使用 " + getAxe() + "砍柴!");
        System.out.println(getAxe().chop());
    }
}

实际上,Spring实现getAxe()的逻辑是:

public Axe getAxe()
{
    return ctx.getBean("steelAxe");
}

运行结果:

  • Spring实例化主调bean:Chinese实例...
  • Spring实例化依赖Bean:SteelAxe实例...
2015/10/25

---

layout: post
title: "Spring Bean的生命周期"
category: Reading Notes

tags: ["读书", "Spring"]

{% include JB/setup %}

Spring Bean生命周期

依赖关系注入之后的行为

<bean id="chinese" class="..." init-method="init">
    <property name="axe" ref="steelAxe"/>
</bean>

public class Chinese implements Person, InitializingBean
{
    private Axe axe;

    public Chinese()
    {
        System.out.println("Spring实例化主调bean:Chinese实例...");
    }

    public void setAxe(Axe axe)
    {
        System.out.println("Spring执行依赖关系注入...");
        this.axe = axe;
    }

    public void useAxe()
    {
        System.out.println(axe.chop());
    }

    public void init()
    {
        System.out.println("正在执行初始化方法 init...");
    }

    public void afterPropertiesSet() throws Exception
    {
        System.out.println("正在执行初始化方法 afterPropertiesSet...");
    }
}

主程序的执行结果如下:

  • Spring实例化依赖bean:SteelAxe实例...
  • Spring实例化主调bean:Chinese实例...
  • Spring执行依赖关系注入...
  • 正在执行初始化方法 afterPropertiesSet...
  • 正在执行初始化方法 init...
  • axe.chop()

Bean销毁之前的行为

<bean id="chinese" class="..." close-method="close">
    <property name="axe" ref="steelAxe"/>
</bean>

public class Chinese implements Person, DisposableBean
{
    private Axe axe;

    public Chinese()
    {
        System.out.println("Spring实例化主调bean:Chinese实例...");
    }

    public void setAxe(Axe axe)
    {
        System.out.println("Spring执行依赖关系注入...");
        this.axe = axe;
    }

    public void useAxe()
    {
        System.out.println(axe.chop());
    }

    public void close()
    {
        System.out.println("正在执行销毁之前的方法 close...");
    }

    public void destroy() throws Exception
    {
        System.out.println("正在执行销毁之前的方法 destroy...");
    }
}

如果容器中很多Bean都需要指定特定的生命周期行为,则可以利用元素的default-init-method属性和default-destroy-method属性。

spring中bean生命周期.png

2015/10/25

---

layout: post
title: "设计模式——工厂模式"
category: Reading Notes

tags: ["读文章", “设计模式”]

{% include JB/setup %}

工厂模式

主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的

Factory design pattern is used for creating an object based on different parameters. The example below is about creating human in a factory. If we ask the factory for a boy, the factory will produce a boy; if we ask for a girl, the factory will produce a girl. Based on different parameters, the factory produce different stuff.

简单工厂模式

组成:

  1. 工厂类角色:含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现
  2. 抽象产品角色:一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现
  3. 具体产品角色:

    //抽象产品角色
    public interface Car {
        public void drive(); 
    }
    
    //具体产品角色
    public class Benz implements Car{
        public void drive()  {
            System.out.println("Driving Benz ");
        }
    }
    
    public class Bmw implements Car{
        public void drive()  {
            System.out.println("Driving Bmw ");
        }
    }
    
    ....
    
    //工厂类角色
    public class Driver 
    {
        //工厂方法.注意 返回类型为抽象产品角色
        public static Car driverCar(String s)throws Exception {
            //判断逻辑,返回具体的产品角色给Client
            if(s.equalsIgnoreCase("Benz"))  
                return new Benz();
            else if(s.equalsIgnoreCase("Bmw"))
                return new Bmw();
    
            .... 
    
            else 
                throw new Exception();
    
    ....
    
    //欢迎暴发户出场......
    public class Magnate {
        public static void main(String[] args){
            try
            { 
                //告诉司机我今天坐奔驰  
                Car car = Driver.driverCar("benz"); 
                //下命令:开车   
                car.drive();
    ....
    

当暴发户增加了一辆车的时候,只要符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。

但是工厂部分好像不太理想,因为每增加一辆车,都要在工厂类中增加相应的业务逻辑或者判断逻辑,这显然是违背开闭原则的。

工厂方法模式

工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。

组成

  1. 抽象工厂角色:是具体工厂角色必须实现的接口或者继承的父类。在java中它由抽象类或者接口来实现
  2. 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象
  3. 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现
  4. 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现

    //抽象产品角色
    public interface Car {
        public void drive(); 
    }
    
    public class Benz implements Car{
        public void drive()  {
            System.out.println("Driving Benz ");
        }
    }
    
    public class Bmw implements Car{
        public void drive()  {
            System.out.println("Driving Bmw ");
        }
    }
    
    //抽象工厂角色
    public interface Driver{
       public Car driverCar();
    }
    
    public class BenzDriver implements Driver{
       public Car driverCar() {
              return new Benz();
       }
    }
    public class BmwDriver implements Driver{
       public Car driverCar() {
            return new Bmw(); 
       }
    }
    
    public class Magnate
    {
          public static void main(String[] args)
          {
                 try
                 { 
                        Driver driver = new BenzDriver();
                        Car car = driver.driverCar();
                        car.drive();
                 }
    ……
    }
    
2015/10/25

---

layout: post
title: "设计模式——单例模式"
category: Reading Notes

tags: ["读文章", “设计模式”]

{% include JB/setup %}

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式中的‘单例’通常用来代表那些本质上具有唯一性的系统组件(或者叫做资源)。比如文件系统、资源管理器等。

实现一:

public class Singleton {

    //在自己内部定义自己一个实例
    //注意这是private 只供内部调用
    private static Singleton instance = new Singleton();

    //如上面所述,将构造函数设置为私有
    private Singleton(){
    } 

    //静态工厂方法,提供了一个供外部访问得到对象的静态方法  
  public static Singleton getInstance() {
    return instance;   
  } 
}

下面这种方式被称为懒汉式

实现二:

public class Singleton {

    //和上面有什么不同?
    private static Singleton instance = null;

    //设置为私有的构造函数
    private Singleton(){
    } 

    //静态工厂方法
    public static synchronized Singleton getInstance() {
        //这个方法比上面有所改进
         if (instance==null)
              instance=new Singleton();
         return instance;   
    }
}
  1. 他们的构造函数都是私有的,彻底断开了使用构造函数来得到类的实例的通道,但是这样也使得类失去了多态性
  2. 在第二种方式中,对静态工厂方法进行了同步处理,为了防止多线程环境中产生多个实例;而在第一种方式中则不会存在这样的问题
  3. 在第二种方式中,将类对自己的实例化延迟到第一次被引用的时候。而在第一种方式中则是在类被加载的时候

这样一来每次调用getInstance()方法是都会被加锁,而我们只需要在第一次调用getInstance()的时候加锁就可以了。这显然影响了我们程序的性能。

//内部类实现懒汉式  
public class Singleton {  
    private static class SingletonHolder{  
        //单例变量    
        private static Singleton instance = new Singleton();  
    }  

    //私有化的构造方法,保证外部的类不能通过构造器来实例化。  
    private Singleton() {  

    }  

    //获取单例对象实例  
    public static Singleton getInstance() {  
        System.out.println("我是内部类单例!");  
        return SingletonHolder.instance;  
    }  
}  
因为java机制规定,内部类SingletonHolder只有在getInstance()方法第一次调用的时候才会被加载(实现了lazy),而且其加载过程是线程安全的(实现线程安全)。内部类加载的时候实例化一次instance
2015/10/25

---

layout: post
title: "Bit map 概念和原理"
category: Reading Notes

tags: ["读文章", "算法"]

{% include JB/setup %}

什么是Bit-map

所谓的bit-map就是用一个bit位来标记某个元素对应的Value,而key即是该元素。由于采用了bit为单位来存储数据,因此在存储空间方面,可以大大节省。

例子

假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复)。那么我们就可以采用Bit-map的方法来达到排序的目的。要表示8个数,我们就只需要8个Bit(1Bytes),首先我们开辟1Byte的空间,将这些空间的所有Bit位都置为0(如下图:)

bitmap1

然后遍历这5个元素,首先第一个元素是4,那么就把4对应的位置为1

bitmap2

然后再处理第二个元素7,将第八位置为1,,接着再处理第三个元素,一直到最后处理完所有的元素,将相应的位置为1,这时候的内存的Bit位的状态如下:

bitmap3

然后我们现在遍历一遍Bit区域,将该位是一的位的编号输出(2,3,4,5,7),这样就达到了排序的目的。下面的代码给出了一个BitMap的用法:排序。

2015/10/25