zoukankan      html  css  js  c++  java
  • 3. Spring配置文件

    Spring配置文件

    【对 第一个 HelloWorld 程序】 进行解刨知识点

    1.Bean标签基本配置

    用于配置对象交由Spring 来创建。 默认情况下它调用的是类中的无参构造函数如果没有无参构造函数则不能创建成功。【这种方法叫做 无参方法实例化 Bean对象是根据它的无参构造来获取的】

    基本属性:  id:Bean实例在Spring容器中的唯一标识 【emm 唯一标识 真是个常识.】

    class:Bean的全限定名称  【记得带包名 而且方法要有无参构造】

    2.Bean标签范围配置

    除了 Id 和 Class ,Bean标签还有一个属性 scope : 学过JSP都知道 是域、范围的意思.

    scope:指对象的作用范围,取值如下:

    取值范围

    说明

    singleton

    默认值,单例的

    prototype

    多例的

    request

    WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中

    session

    WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中

    global session

    WEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession相当于 session

    所以 我们没配置 他就会 singleton 单的,我们先详说 singletion 和 prototype :

    因为其他设计到了 WEB 项目:

    Bean标签范围配置

    1)当scope的取值为singleton时  Bean的实例化个数:1个  【无参构造 只执行一次】

    Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例  【意思是说 emmmm 在获取到XML对象时 只执行一次无参构造 那么证明只实例化一次 以后都是同一对象 而且 只有一个Bean对象 因为是singleton 单例 】

    Bean的生命周期: 对象创建:当应用加载,创建容器时,对象就被创建了  【出生】

    对象运行:只要容器在,对象一直活着    【活着】

    对象销毁:当应用卸载,销毁容器时,对象就被销毁了    【销毁】

    2)当scope的取值为prototype Bean的实例化个数:多个  【实例化一个 就执行一次无参构造】

    Bean的实例化时机:当调用getBean()方法时实例化Bean        【意思是说 emmmm 在获取到XML对象时 不会实例化 当 getBean 时 会执行无参构造一次  每一次都是不同的对象 不同的Bean】

    对象创建:当使用对象时,创建新的对象实例

    对象运行:只要对象在使用中,就一直活着

    对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了

    例: 【Junit 测试:】

    HelloServer.java : 【接口】

    package com.bihu.helloDao;
    
    public interface HelloService {
        void show();
    }
    HelloServiceImpl.java :  【实现类】
    package com.bihu.helloImpl;
    
    import com.bihu.helloDao.HelloService;
    
    public class HelloServiceImpl implements HelloService {
    
        //无参构造:
    
    
        public HelloServiceImpl() {
            System.out.println("实例化了一个 HelloServiceImpl 对象 执行了无参构造");
        }
    
        public void show() {
            System.out.println("Hello World!");
        }
    }

    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
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--  默认 singleton【单例】 自行更换 prototype【多例】   -->
        <bean id="hello_bean" class="com.bihu.helloImpl.HelloServiceImpl" scope="singleton" ></bean>
    </beans>

    Test:   【一般测试类 都新建一个文件夹 Test 然后里面包都和 main 的差不多 其实就是 一个 java  一个 resource 】

    import com.bihu.helloImpl.HelloServiceImpl;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class test {
    
        @Test //要导入 Junit 的 GAV
        public void springTest(){
            //获取XML
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            //实例化两个 HelloServiceImpl 对象:
             HelloServiceImpl app1  = (HelloServiceImpl)app.getBean("hello_bean");
             HelloServiceImpl app2  = (HelloServiceImpl)app.getBean("hello_bean");
    
             //分别打印他的地址 如果在你spring配置文件中的Bean 是singleton 的话 地址会一样,如果是prototype的话 会不一样 其次执行的无参构造次数也不一样
            // 所以可以根据它的特性来DEBUG:
            System.out.println(app1);
            System.out.println(app2);
    
        }
    
    
    }

    所以 单例 和 多例的区别 就在这里 自己测试即可.

    3. Bean生命周期配置

    init-method:指定类中的初始化方法名称

    destroy-method:指定类中销毁方法名称

    直接在 Bean 中配 即可 ,但是确保 Bean中有函数存在,例:

    当然名字你自己设置啊 自定义.

    HelloServiceImpl.java 
    package com.bihu.helloImpl;
    
    import com.bihu.helloDao.HelloService;
    
    public class HelloServiceImpl implements HelloService {
    
        //无参构造:
    
    
        public HelloServiceImpl() {
            System.out.println("实例化了一个 HelloServiceImpl 对象 执行了无参构造");
        }
    
        public void show() {
            System.out.println("Hello World!");
        }
    
    
        /*--初始化 和 销毁 方法: --*/
        public void init() {
            System.out.println("Bean出生了");
        }
    
        public void destroy() {
            System.out.println("Bean销毁了");
        }
    
    }

    Spring配置文件:

    <?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
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--  默认 singleton【单例】 自行更换 prototype【多例】   -->
        <bean id="hello_bean" class="com.bihu.helloImpl.HelloServiceImpl" scope="singleton" init-method="init" destroy-method="destroy" ></bean>
    </beans>

    测试: 当你单单获取xml 的话 他会执行 init方法 因为在spring中设置了

    import com.bihu.helloImpl.HelloServiceImpl;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class test {
    
        @Test //要导入 Junit 的 GAV
        public void springTest(){
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        }
    }

    它的输出:

    信息: Loading XML bean definitions from class path resource [applicationContext.xml]
    实例化了一个 HelloServiceImpl 对象 执行了无参构造
    Bean出生了
    
    Process finished with exit code 0

    但是 没执行销毁方法 因为 emmmm 没来得及打印....

    如果你实在想去测试,那么:

    import com.bihu.helloImpl.HelloServiceImpl;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class test {
    
        @Test //要导入 Junit 的 GAV
        public void springTest(){
            //ApplicationContext 改成了 ClassPathXmlApplicationContext,因为ClassPathXmlApplicationContext是ApplicationContext的实现类,所以有close方法.
            ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            app.close();    //关掉 所以就可以自动调用 销毁方法了
    
            //这个理解即可 知道那个原理
        }
    }

    输出:

    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@574caa3f: startup date [Fri Jun 18 11:57:00 CST 2021]; root of context hierarchy
    六月 18, 2021 11:57:00 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [applicationContext.xml]
    实例化了一个 HelloServiceImpl 对象 执行了无参构造
    Bean出生了
    六月 18, 2021 11:57:00 上午 org.springframework.context.support.AbstractApplicationContext doClose
    信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@574caa3f: startup date [Fri Jun 18 11:57:00 CST 2021]; root of context hierarchy
    Bean销毁了

    4.Bean实例化三种方式

    1.无参构造方法实例化 

    2.工厂静态方法实例化

    3.工厂实例方法实例化

    第一种不多说 上面那个就是 无参构造方法实例化

    工厂静态方法实例化:

    说到工厂 就想起 factory ,就想到工厂模式,而且是静态的:

    其实就是 返回一个指定的对象回去(工厂) ,然后在Spring配置文件中配置【Class变为 工厂模式的地址 、 添加 factory-method 字段,值是工厂类的方法【返回对象那个方法】】

    其实就是反射,接下来看代码:

    先创建一个静态工厂  这里是 StaticFactroy类:

    package com.bihu.factroy;
    
    import com.bihu.helloImpl.HelloServiceImpl;
    
    //静态工厂
    public class StaticFactroy {
        public static HelloServiceImpl GetHelloServiceImpl(){
            return new HelloServiceImpl();
        }
    }

    然后我们配置Spring文件:

    <?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
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--静态工厂实例化:-->
        <bean id="StaticFactory" class="com.bihu.factroy.StaticFactroy" factory-method="GetHelloServiceImpl"></bean>
    
    </beans>

    记住 静态工厂实例化模式是factory-method 一个就够!!!

    然后我们测试:Test.java:

    <?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
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--静态工厂实例化:-->
        <bean id="StaticFactory" class="com.bihu.factroy.StaticFactroy" factory-method="GetHelloServiceImpl"></bean>
    
    </beans>

    输出:

    信息: Loading XML bean definitions from class path resource [applicationContext.xml]
    实例化了一个 HelloServiceImpl 对象 执行了无参构造
    Hello World!
    
    Process finished with exit code 0

    证明是 毫无问题的 这种。

    工厂实例方法实例化

    刚刚是静态的 这次来个不是静态的:

    想想看 既然是工厂实例方法 少不了创建工厂模式,但是由于不是静态的话 肯定要先获取到他的工厂实例 然后配置哪方面: 肯定要先有工厂Bean  那么就是 先创建一个工厂Bean 然后跟着这个工厂Bean进去找方法即可 完成实例化 Bean.

    其中 在Spring的配置文件中 获取 工厂Bean 是:factory-bean 属性,值是 自己配的 工厂Bean,所以工厂Bean 相当于Class 。

    所以大体思路 唯一要改的就是 Spring的配置文件 和 去掉静态方法  上代码:

    package com.bihu.factroy;
    
    import com.bihu.helloImpl.HelloServiceImpl;
    
    //工厂模式实例化
    public class StaticFactroy {
        public HelloServiceImpl GetHelloServiceImpl(){
            return new HelloServiceImpl();
        }
    }

    去掉静态的啊 因为是工厂实例方法实例化...有点绕口..

    然后是Spring 配置文件:

    <?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
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--工厂实例化:-->
    <!--  因为不是静态的 所以先创建一个FactoryBean,在通过FactoryBean去反射找到指定的方法 实例化   Bean  -->
    
    <!-- 先获取工厂Bean:   -->
        <bean id="FactoryBean" class="com.bihu.factroy.StaticFactroy"></bean>
    
    <!-- 然后根据工厂Bean获取指定方法获取Bean   -->
        <bean id="Bean" factory-bean="FactoryBean" factory-method="GetHelloServiceImpl" ></bean>
    </beans>

    其实这里的  FactoryBean 相当于 静态工厂模式的 Class .

    说那么多 已经是很保姆级别的了  请带脑子阅读...

    测试: Test.java :

    import com.bihu.helloImpl.HelloServiceImpl;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class test {
    
        @Test //要导入 Junit 的 GAV
        public void springTest(){
            ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            HelloServiceImpl staticFactory = (HelloServiceImpl)app.getBean("Bean");
            staticFactory.show();
        }
    }

    Bean 差不多了... 主要还是要有反射思维...

    注意: 不要看这里的包名 我乱打的!!! 和MVC模式对不上的!不是MVC模式!!! 你只需知道 一个接口 一个实现即可,因为是测试 所以没认真看包名.你只需要知道 那个是接口 那个是实现即可,真正的MVC模式命名和归类是很规范的.

    完.

    本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/14898630.html

  • 相关阅读:
    C语言第三次博客作业---单层循环结构
    C语言第二次博客作业---分支结构
    C语言第一次博客作业
    第0次作业
    第09组 Beta冲刺(1/5)
    第09组 Alpha事后诸葛亮
    第09组 Alpha冲刺(6/6)
    第09组 Alpha冲刺(5/6)
    第09组 Alpha冲刺(4/6)
    第09组 Alpha冲刺(3/6)
  • 原文地址:https://www.cnblogs.com/bi-hu/p/14898630.html
Copyright © 2011-2022 走看看