Spring的IOC学习之二

IOC的介绍与使用

1. IOC的介绍

IOC是控制反转,是spring中的一个非常重要一个特性,IOC也称为DI即依赖注入。简而言之就是把spring变成一个容器,由spring来控制对象的创建和他们之间的依赖关系。下面通过一个例子来熟悉spring的IOC的使用与意义。
例:有一个战士(Knight)类,战士有不同的武器,用java实现如下:

  • 创建战士类Knight.java。
    这个类里有两个属性,用户名(username)和武器(weapon)。武器属性的类型是一个接口weapon,这个接口里只包括一个空方法attack()。在knight.java里面为相应的属性添加getter和setter方法以及构造方法,再编写一个fight()方法,执行weapon的attack方法。
public class Knight {
    private String username;
    private Weapon weapon;

    public Knight() {
    }

    public Knight(String username, Weapon weapon) {
        this.username = username;
        this.weapon = weapon;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Weapon getWeapon() {
        return weapon;
    }
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
    public void fight(){
        System.out.println(username+"开始攻击了");
        weapon.attack();
    }
}

public interface Weapon {
    void attack();
}

  • 创建武器的一些类,比如刀Knife,斧子Axe,枪Gun。它们都实现weapon接口。
public class Knife implements Weapon {
    public void attack() {
        System.out.println("拿起了刀");
    }
}
....
public class Axe implements Weapon {
    public void attack() {
        System.out.println("拿起了斧子");
    }
}
....
public class Gun implements Weapon {
    public void attack() {
        System.out.println("拿起了枪");
    }
}

那么knight中如何创建Weapon呢?开始大家都会直接使用new来创建具体的weapon实例,但这种方法过于依赖一个具体的实现类,如果要修改武器的种类,那么所有的都要修改,没有灵活性。还有一种基于工厂的模式来创建,这里给出使用简单的工厂来演示。

public class SimpleFactory{
      public static Weapon getWeapon(){
              return new Knife();
}
....
public class Test{
       public static void main(String[] args){
              Weapon w= SimpleFactory.getWeapon();
              Knight k=new Knight("老王",w);
              k.fight();
}
}

这种基于工厂的模式创建实例解决了灵活性的问题,但调整的时候要修改原代码SimpleFactory,因此也不是很理想。最佳的方式是将具体的类写到配置文件中,通过读取配置文件来创建具体的对象。下面给出这种方式的方法。

2.创建配置文件存储具体的对象
  • 创建beans.properties文件,加上下面这个代码
weapon=com.lu.spring.base.Gun
  • 为方便确定哪些对象需要创建,可以自己定义一个Annotation来指定要创建的对象
@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {
    public String value()default "";
}

然后在需要创建的对象的setter方法上添加该Annotation

@Inject
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
  • 创建一个基类,在基类中创建所有的对象,让所有需要添加这个对象的类继承这个基类。
public class Base {
    public Base(){
        Method[] ms=this.getClass().getMethods();
        Properties pro=new Properties();
        try {
            pro.load(Base.class.getClassLoader().getResourceAsStream("beans.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        for(Method m:ms){
            if(m.isAnnotationPresent(Inject.class)){
              String mname=m.getName();
              mname=mname.substring(3);
              mname=mname.substring(0,1).toLowerCase()+mname.substring(1);//weapon
                System.out.println(mname);
                String cname= (String) pro.get(mname);
                Object o= null;
                try {
                    o = Class.forName(cname).newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                try {
                    m.invoke(this,o);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

如此以来,只要创建Knight,就会自动调用父类不带参数的构造方法来完成对象的注入,这就是依赖注入。只要继承Base的所有类都支持这种依赖注入的方式,这就是spring的DI所做的事情。
以上内容只是spring的简单学习,如有不足,望请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值