SpringIOC配置文件「bean」标签的属性id class name scope init-method destroy-method factory-bean factory-method

29 篇文章 0 订阅

spring

引入Spring

在没有使用spring的时候写代码的三层架构的时候,dao层与service紧密联系,service与controller紧密联系,在service中new的dao接口的实现类,在controller中new的是service的实现类,这种联系很紧密,高耦合

图解spring是如何降低耦合度的

原始模式

在最初的代码是要使用的话,就new这个接口的实现对象,假如我们换实现类后,还需要更改源代码,这样耦合度高,加入我们项目上线后,我们要更改某个实现,需要更改源代码,需要从新编译部署运行,十分麻烦
在这里插入图片描述

工厂模式降低解耦

使用工厂模式,让new实现类的工作交给工厂来创建,这样虽然具体的业务和实现类是断开了耦合,但是工厂与实现类还是高耦合,我们想修改实现类,还得修改工厂中的方法,导致还是需要从新编译打包部署运行
在这里插入图片描述

spring的IOC

使用spring来管理我们的实体对象,只需要将配置文件中的实现更改,无需更改源代码,当我们需要跟换实现的时候,只需要将配置文件中的class更改就行了,无需重新编译,十分方便,从而使得代码与代码之间的耦合度降低,让类与配置文件有紧密联系
在这里插入图片描述

耦合与内聚

在这里插入图片描述

IOC

IoC
⚫ IoC(Inversion Of Control)控制反转,Spring反向控制应用程序所需要使用的外部资源
⚫ Spring控制的资源全部放置在Spring容器中,该容器称为IoC容器

通俗来将就是原本我们使用一个类需要将这个类new出来,是我们主动去创建这个类
而把这个类交给spring的ioc管理后,spring会把这个类放在他的ioc容器中,然后我们要使用就去容器中获取就是,被动获取
在这里插入图片描述

spring的applicationContext.xml关于IOC的配置

记录spring的applicationContext.xml配置文件中的bean标签的使用

bean
⚫ 名称:bean
⚫ 类型:标签
⚫ 归属:beans标签
⚫ 作用:定义spring中的资源,受此标签定义的资源将受到spring控制
⚫ 格式:
< beans>
< bean />
< /beans>

基本属性id属性和class属性< bean id=“dog” class=“com.fs.iocdemo.Dog”/>

< bean id=“dog” class=“com.fs.iocdemo.Dog”/>
◆ id:bean的名称,通过id值获取bean
◆ class:bean的类型

类的准备

创建一个Dog类,提供一个方法来输出语句便于观察

package com.fs.iocdemo;

public class Dog {
    public void testBean(){
        System.out.println("Dog对象被spring管理了");
    }
}

配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    把Dog对象交给spring的ioc容器管理,默认通过无参构造方法创建-->
    <bean id="dog" class="com.fs.iocdemo.Dog"/>
</beans>
测试方法
    //测试bean是否被ioc管理
    @Test
    public void testBean() {
        //创建spring的ioc容器对象,传递的参数为配置文件的名,类路径下的配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //通过配置文件中的id从spring的ioc容器中获取Dog对象
        Dog dog = (Dog) applicationContext.getBean("dog");
        //调用方法
        dog.testBean();
    }
输出结果与解释

说明我们的Dog已经从spring的IOC容器中获取到了

在这里插入图片描述

基本属性name < bean id=“cat” name=“cat1,cat2” class=“com.fs.iocdemo.Cat”/>

◆ name:bean的名称,可以通过name值获取bean,用于多人配合时给bean起别名

类的准备

创建一个Cat类,来演示一个配置文件中可以将多个类交给spring的Ioc管理,和演示name属性

package com.fs.iocdemo;

public class Cat {

    public void testName(){
        System.out.println("cat被spring的ioc管理了");
    }

}

配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    把Dog对象交给spring的ioc容器管理,默认通过无参构造方法创建-->
    <bean id="dog" class="com.fs.iocdemo.Dog"/>

<!--把Cat对象交给spring的ioc容器管理,并且给多个name(起别名),通过getBean可以给别名从ioc中的到对象-->
    <bean id="cat" name="cat1,cat2" class="com.fs.iocdemo.Cat"/>

</beans>
测试方法
    //测试给bean起别名后,通过别名从ioc中获取对象
    @Test
    public void testName() {
        //创建spring的ioc容器对象,传递的参数为配置文件的名,类路径下的配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //通过配置文件中的id从spring的ioc容器中获取Dog对象
//        Cat cat = (Cat) applicationContext.getBean("cat");
        //使用别名也可以从spring的ioc获取出Cat对象
//        Cat cat = (Cat) applicationContext.getBean("cat1");
        Cat cat = (Cat) applicationContext.getBean("cat2");
        //调用方法
        cat.testName();
    }
输出结果与解释

由上面代码可得,getBean(这里可以传递id,也可以传递name),别名起多个,也可以从springIOC中获取
在这里插入图片描述

基本属性scope < bean id=“cat3” scope=“singleton” class=“com.fs.iocdemo.Cat”/>

bean属性scope
⚫ 名称:scope
⚫ 类型:属性
⚫ 归属:bean标签
⚫ 作用:定义bean的作用范围
⚫ 格式:< bean scope=“singleton”>
⚫ 取值:
◆ singleton:设定创建出的对象保存在spring容器中,是一个单例的对象
◆ prototype:设定创建出的对象保存在spring容器中,是一个非单例的对象
◆ request、session、application、 websocket :设定创建出的对象放置在web容器对应的位置

类依然使用Cat类
配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    把Dog对象交给spring的ioc容器管理,默认通过无参构造方法创建-->
    <bean id="dog" class="com.fs.iocdemo.Dog"/>

<!--把Cat对象交给spring的ioc容器管理,并且给多个name(起别名),通过getBean可以给别名从ioc中的到对象-->
    <bean id="cat" name="cat1,cat2" class="com.fs.iocdemo.Cat"/>

<!--bean中的scope属性默认是单例的(singleton)而且是俄汉式,就是类一加载就创建(不写scope就是单例)
            scope属性的prototype是多列的,但是是懒汉式,需要的后才创建
  -->
<!--    <bean id="cat3" scope="singleton" class="com.fs.iocdemo.Cat"/>-->
    <bean id="cat3" scope="prototype" class="com.fs.iocdemo.Cat"/>

</beans>
测试方法
    //测试bean标签的scope属性单例和多列模式
    @Test
    public void testScope() {
        //创建spring的ioc容器对象,传递的参数为配置文件的名,类路径下的配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        /*

        <bean id="cat2" scope="singleton" class="com.fs.iocdemo.Cat"/>
        //单列模式获取多个对象,看地址是否一样,一样说明确实是单例
        Cat cat = (Cat) applicationContext.getBean("cat3");
        Cat cat1 = (Cat) applicationContext.getBean("cat3");
        Cat cat2 = (Cat) applicationContext.getBean("cat3");
        //输出看下地址值
        System.out.println(cat);//com.fs.iocdemo.Cat@7a765367
        System.out.println(cat1);//com.fs.iocdemo.Cat@7a765367
        System.out.println(cat2);//com.fs.iocdemo.Cat@7a765367

        */

        //多列模式下输出的地址值不一样,所明确实是的
        //多列模式spring是不会吧对象放在ioc中的,只是帮我们new的一下
        //<bean id="cat3" scope="prototype" class="com.fs.iocdemo.Cat"/>
        Cat cat = (Cat) applicationContext.getBean("cat3");
        Cat cat1 = (Cat) applicationContext.getBean("cat3");
        Cat cat2 = (Cat) applicationContext.getBean("cat3");
        //输出看下地址值
        System.out.println(cat);//com.fs.iocdemo.Cat@7a765367
        System.out.println(cat1);//com.fs.iocdemo.Cat@76b0bfab
        System.out.println(cat2);//com.fs.iocdemo.Cat@17d677df
    }

运行结果

在测试代码的输出语句中有显示,可以得到当单例的时候,得到的对象都是同一个,而且是从IOC中获取的对象,而多列的时候,获取的对象是多个,而且不是从SpringIOC中获取的,因为是多列,每获取spring只帮new出来,而不会存储在IOC中

Bean的生命周期 < bean id=“cat4” scope=“prototype” init-method=“init” destroy-method=“destroy” class=“com.fs.iocdemo.Cat”/>

bean生命周期
⚫ 名称:init-method,destroy-method
⚫ 类型:属性
⚫ 归属:bean标签
⚫ 作用:定义bean对象在初始化或销毁时完成的工作
⚫ 格式:<bean init-method=“init” destroy-method="destroy>
⚫ 取值:bean对应的类中对应的具体方法名
⚫ 注意事项:
◆ 当scope=“singleton”时,spring容器中有且仅有一个对象,init方法在创建容器时仅执行一次
◆ 当scope=“prototype”时,spring容器要创建同一类型的多个对象,init方法在每个对象创建
时均执行一次
◆ 当scope=“singleton”时,关闭容器会导致bean实例的销毁,调用destroy方法一次
◆ 当scope=“prototype”时,对象的销毁由垃圾回收机制gc()控制,destroy方法将不会被执行

类的准备

在类中创建一个构造方法,两个随意的方法,名字也随意,打印输出一下,方便查看效果

package com.fs.iocdemo;

public class Cat {

    public Cat() {
        System.out.println("构造方法执行了");
    }

    public void testName(){
        System.out.println("cat被spring的ioc管理了");
    }

    public void init(){
        System.out.println("init方法执行了");
    }

    public void destroy(){
        System.out.println("destroy方法执行了");
    }
}

配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    把Dog对象交给spring的ioc容器管理,默认通过无参构造方法创建-->
    <bean id="dog" class="com.fs.iocdemo.Dog"/>

<!--把Cat对象交给spring的ioc容器管理,并且给多个name(起别名),通过getBean可以给别名从ioc中的到对象-->
    <bean id="cat" name="cat1,cat2" class="com.fs.iocdemo.Cat"/>

<!--bean中的scope属性默认是单例的(singleton)而且是俄汉式,就是类一加载就创建(不写scope就是单例)
            scope属性的prototype是多列的,但是是懒汉式,需要的后才创建
  -->
<!--    <bean id="cat3" scope="singleton" class="com.fs.iocdemo.Cat"/>-->
    <bean id="cat3" scope="prototype" class="com.fs.iocdemo.Cat"/>

<!--
init-method:给的类中的一个方法        在对象创建后执行
destroy-method:给类中的一个方法         在ioc容器正常关闭的时候运行,需要使用ClassPathXmlApplicationContext中的close()关闭才会执行
-->
    <bean id="cat4" scope="prototype" init-method="init" destroy-method="destroy" class="com.fs.iocdemo.Cat"/>

</beans>
测试方法
    //测试bean的生命周期
    @Test
    public void testInitDestroy() {
        //创建spring的ioc容器对象,传递的参数为配置文件的名,类路径下的配置文件
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //不需要从ioc中获得对象,因为spring一读取配置文件就创建对象存在ioc中,所以默认无参构造方法就执行了
        //    <bean id="cat4" scope="singleton" init-method="init" destroy-method="destroy" class="com.fs.iocdemo.Cat"/>
        /*
        单例模式(单列模式创建的对象会交给springIOC管理)
        构造方法执行了
        构造方法执行了
        init方法执行了
        destroy方法执行了
         */

        //    <bean id="cat4" scope="prototype" init-method="init" destroy-method="destroy" class="com.fs.iocdemo.Cat"/>
        //多列测试
        Cat cat = (Cat) applicationContext.getBean("cat4");
        Cat cat2 = (Cat) applicationContext.getBean("cat4");
        Cat cat3 = (Cat) applicationContext.getBean("cat4");

        /*

        多列模式下不会执行destroy方法
        (多列创建的对象不会交个spring的IOC管理,创建后就没有被真正的关闭,而是被jvm垃圾回收,所以不会立马执行destroy)
        构造方法执行了
        构造方法执行了
        init方法执行了
        构造方法执行了
        init方法执行了
        构造方法执行了
        init方法执行了

         */

        //ClassPathXmlApplicationContext 的close()关闭spring让destroy执行
        applicationContext.close();
    }

运行结果

代码中有注释运行结果,也有解释.

bean对象的创建方式

使用静态工厂和实例工厂创建bean

使用静态工厂方式

bean对象创建方式(了解)
⚫ 名称:factory-bean
⚫ 类型:属性
⚫ 归属:bean标签
⚫ 作用:定义bean对象创建方式,使用静态工厂的形式创建bean,兼容早期遗留系统的升级工作
⚫ 格式:
⚫ 取值:工厂bean中用于获取对象的静态方法名
⚫ 注意事项:
◆ class属性必须配置成静态工厂的类名

静态工厂类

静态工厂获取Dog只需要FactoryStatic.Dog就能得到Dog对象

package com.fs.factory;

import com.fs.iocdemo.Dog;

public class FactoryStatic {
    //这个静态工厂,用于生产dog
    public static Dog getDog(){
        return new Dog();
    }
}

实例工厂类

实例工厂获取Dog,首先需要 new FactoryBean().getDog() 才能获得Dog对象

package com.fs.factory;

import com.fs.iocdemo.Dog;

public class FactoryBean {
    //这是个实体类工厂,用于生产Dog
    public Dog getDog(){
        return new Dog();
    }
}

配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

<!--    把Dog对象交给spring的ioc容器管理,默认通过无参构造方法创建-->
    <bean id="dog" class="com.fs.iocdemo.Dog"/>

<!--把Cat对象交给spring的ioc容器管理,并且给多个name(起别名),通过getBean可以给别名从ioc中的到对象-->
    <bean id="cat" name="cat1,cat2" class="com.fs.iocdemo.Cat"/>

<!--bean中的scope属性默认是单例的(singleton)而且是俄汉式,就是类一加载就创建(不写scope就是单例)
            scope属性的prototype是多列的,但是是懒汉式,需要的后才创建
  -->
<!--    <bean id="cat3" scope="singleton" class="com.fs.iocdemo.Cat"/>-->
    <bean id="cat3" scope="prototype" class="com.fs.iocdemo.Cat"/>

<!--
init-method:给的类中的一个方法        在对象创建后执行
destroy-method:给类中的一个方法         在ioc容器正常关闭的时候运行,需要使用ClassPathXmlApplicationContext中的close()关闭才会执行
-->
    <bean id="cat4" scope="prototype" init-method="init" destroy-method="destroy" class="com.fs.iocdemo.Cat"/>



<!--    配置静态工厂交给spring管理
        因为获取Dog的方法是静态的,当我们从ioc获取出静态工厂就直接调用getDog方法就能拿到Dog
        //实际是将getDog的返回值存储在ioc容器中
-->
    <bean id="factoryStatic" class="com.fs.factory.FactoryStatic" factory-method="getDog"/>

<!--    配置实体工厂-->
    <bean id="factoryBean" class="com.fs.factory.FactoryBean"/>
<!--    然后在实体工厂中获取Dog
        factory-bean="factoryBean" : 关联上面的实体工厂
        factory-method="getDog" : 调用实体工厂的方法
        //实际是将Dog存到ioc容器中
-->
    <bean id="factoryBeanDog" factory-bean="factoryBean" factory-method="getDog"/>

</beans>
测试方法

    //测试工厂获取对象
    @Test
    public void testFactory() {
        //创建spring的ioc容器对象,传递的参数为配置文件的名,类路径下的配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //<bean id="factoryStatic" class="com.fs.factory.FactoryStatic"/>
        Dog factoryStaticDog = (Dog) applicationContext.getBean("factoryStatic");
        factoryStaticDog.testBean();

        /*
    <bean id="factoryBean" class="com.fs.factory.FactoryBean"/>
<!--    然后在实体工厂中获取Dog
        factory-bean="factoryBean" : 关联上面的实体工厂
        factory-method="getDog" : 调用实体工厂的方法
        //实际是将Dog存到ioc容器中
-->
    <bean id="factoryBeanDog" factory-bean="factoryBean" factory-method="getDog"/>
         */
        Dog factoryBeanDog = (Dog) applicationContext.getBean("factoryBeanDog");
        factoryBeanDog.testBean();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值