当前位置: 首页 > 工具软件 > Go-IOC > 使用案例 >

Spring-IOC

帅令雪
2023-12-01

介绍Spring-IOC

Spring-IOC(Inverse Of Control)控制反转。
IOC主要目的就是解耦。
Spring容器借助配置文档将相应的类实例化,进行注入构造器,属性和接口。

立即加载和懒加载

  1. 立即加载:立即加载就是表关联的时候,查询一个对象,会把他关联的对象都查出来初始化到属性中去,这个就是立即加载,所以在查询的时候可能出现多条查询语句

  2. 懒加载:懒加载在你进行数据库查询的时候,不会立即查询关联表的数据库,而是要等到你什么时候需要用到他里面的属性,必须要去查数据库的时候才会去查

懒加载在getBean才将bean加入内存,立即加载在ClassPathXmlApplicationContext就将全部的bean加入内存。

契约式编程

用类名的小写代表对象,比如说ChinesePeople类在契约式编程中chinesePeople作为对象。

BeanFactory和ApplicationContext

BeanFactory是Spring最核心的框架提供了IOC配置机制
通过BeanFactory,启动IoC容器时,并不会再一一次初始化配置文件中定义的Bean,初始化动作发生在第一个调用时BeanFactory会缓存Bean实例,所以第二次使用getBean(),获取bean时将直接从IoC容器的缓存中获取Bean实例。
ApplicationContext是Spring的容器,是建立在BeanFactory基础上的提更了更多面向应用的功能。

BeanFactory和ApplicationContext的区别?
BeanFac tory在初始化容器时,并未实例化Bean,直到第一.次访问某个Bean时才实例目标Bean;
而ApplicationContext.则在初始化应用上下文时就实例化所有单实例的Bean,因此ApplicationContext的初始化时间稍长一些。

IOC的简单使用

xml版

通过一个老师教学生课的例子来实践

构造器注入

Teacher接口:

public interface Teacher {
    public void teach();
}

Bill类:

public class Bill implements Teacher {
    public void teach() {
        System.out.println("我来教课!");
    }
}

Trade接口:

public interface Trade {
    public void to();
}

JavaTrade类:

public class JavaTrade implements Trade {
    private Teacher teacher;

    public JavaTrade(Teacher teacher){
        this.teacher=teacher;
    }

    public void to() {
        this.teacher.teach();
    }
}

常规使用方法:
缺点在于耦合度很高,Teacher和Trade紧紧耦合在一起。

public class Chairman {
    public void go(){
        Teacher tea=new Bill();
        Trade trade=new JavaTrade(tea);//聚合 aggregation
        trade.to();

    }

    public static void main(String[] args) {
        new Chairman().go();
    }
}

采用Spring容器的方法:

public class TestIOC2 {
    public static void main(String[] args) {
//        BeanFactory beanFactory=new ClassPathXmlApplicationContext("applicationContext1.xml");//懒加载
//        JavaTrade j=beanFactory.getBean("java",JavaTrade.class);
//        j.to();

        ApplicationContext beanFactory=new ClassPathXmlApplicationContext("applicationContext1.xml");//立即加载
        JavaTrade j=beanFactory.getBean("java",JavaTrade.class);
        j.to();

    }
}

xml配置文档:

    <!--构造器注入-->
    <beans>
        <!--反射的方式将类反射成对象。-->
        <bean id="bill" class="com.weikun.a.Bill">

        </bean>
        <bean id="java" class="com.weikun.a.JavaTrade">
            <!--property:属性。下面这种方式必许有get、set。ref是指将bill对象送进teacher-->
            <constructor-arg ref="bill"/>
<!--             和上面是等效的   -->
<!--            <constructor-arg >-->
<!--                <ref bean="bill"/>-->
<!--            </constructor-arg>-->
        </bean>
    </beans>

属性注入

Teacher接口:

public interface Teacher {

    public void teach();
}

Bill类:

public class Bill implements Teacher {
    public void teach() {
        System.out.println("我来教课!");
    }
}

Trade接口:

public interface Trade {

    public void to();
}

JavaTrade类:

public class JavaTrade implements Trade {
    private Teacher teacher;


    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public void to() {
        this.teacher.teach();
    }
}

传统方法:

public class Chairman {
    public void go(){
        Teacher tea=new Bill();
        Trade trade=new JavaTrade();//聚合 aggregation
        ((JavaTrade) trade).setTeacher(tea);
        trade.to();

    }

    public static void main(String[] args) {
        new Chairman().go();
    }
}

采用Spring容器方法

public class TestIOC1 {
    public static void main(String[] args) {
        BeanFactory factory=new ClassPathXmlApplicationContext("applicationContext.xml");
        JavaTrade j=factory.getBean("java",JavaTrade.class);
        j.to();

    }
}

xml配置文档

<!--属性注入-->
    <beans>
<!--        反射的方式将类反射成对象。-->
        <bean id="bill" class="com.ruigr.b.Bill">

        </bean>
        <bean id="java" class="com.ruigr.b.JavaTrade">
<!--            property:属性。下面这种方式必许有get、set。ref是指将bill对象送进teacher-->
            <property name="teacher" ref="bill"/>
        </bean>
    </beans>

注解版

Axe接口:

public interface Axe {
    public void chop();

}

SteelAxe类:

@Component
public class SteelAxe implements Axe {//契约式编程
    public void chop() {
        System.out.println("砍柴快!");
    }
}

StoneAxe类:

@Component("myaxe")//<bead id="XXX"
public class StoneAxe implements Axe {
    public void chop() {
        System.out.println("砍柴慢!");
    }
}

Person接口:

public interface Person {

    //定义一个使用斧子的方法
    public void useAxe();

}

Cinese类:

//默认是单例模式(getBean后是一个地址)singleton,也可改成原型模式(getBean后是多个地址)prototype
@Scope("singleton")
@Component
public class Chinese implements Person {

    @Autowired//自动装配  替代了set、get
    @Qualifier("steelAxe")//使用steelAxe
    private Axe axe;

//    public Axe getAxe() {
//        return axe;
//    }
//    @Resource(name="myaxe")//默认使用myaxe
//    public void setAxe(Axe axe) {
//        this.axe = axe;
//    }

    public void useAxe() {
        this.axe.chop();
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("com.weikun.c/beans2.xml");
        Chinese c=ctx.getBean("chinese",Chinese.class);//契约式编程
        System.out.println(c);

        Chinese c1=ctx.getBean("chinese",Chinese.class);//契约式编程
        System.out.println(c1);

        SteelAxe steel=ctx.getBean("steelAxe",SteelAxe.class);
        StoneAxe stone=ctx.getBean("myaxe",StoneAxe.class);

        c.useAxe();

    }
}

xml文档:
注解法采用很少的xml,该段xml文档的作用是限定范围

    <context:component-scan base-package="com.ruigr.d">
            <!--exclude满足正则表达式以Axe结尾的都屏蔽掉,默认是include-->
            <!--<context:exclude-filter type="regex" expression=".*Axe"/>-->
            
    </context:component-scan>
 类似资料: