• Spring入门第二课 Spring中Bean的配置


    这次课我们详细理解一下Spring,理解每一行代码到底是什么意思。

    我们在上次的代码上做一点修改:

    Persion.java

     1 package com.study.entity;
     2 
     3 public class Persion {
     4     
     5     private String name;
     6     private Integer age;
     7     public String getName() {
     8         return name;
     9     }
    10     public void setName(String name) {
    11         System.out.println("setName:"+name);
    12         this.name = name;
    13     }
    14     public Integer getAge() {
    15         return age;
    16     }
    17     public void setAge(Integer age) {
    18         this.age = age;
    19     }
    20     @Override
    21     public String toString() {
    22         return "Persion [name=" + name + ", age=" + age + "]";
    23     }
    24     public Persion(String name, Integer age) {
    25         super();
    26         this.name = name;
    27         this.age = age;
    28     }
    29     public Persion() {
    30         System.out.println("Persion's Contructor....");
    31     }
    32 }

    我们在第10行和第30行加了打印。目的就是我想知道Persion是什么时候被创建了并且设置了属性。

    我们在TestPersion中修改:

     1 package com.study.entity;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 public class TestPersion {
     7 
     8     public static void main(String[] args) {
     9 //        Persion p1 = new Persion();
    10 //        p1.setName("xiaoming");
    11 //        System.out.println(p1.getName());
    12         
    13         //1.创建Spring的IOC容器对象
    14         System.out.println("开始创建Spring的IOC容器");
    15         ApplicationContext ext = new ClassPathXmlApplicationContext("applicationContext.xml");
    16         System.out.println("结束创建Spring的IOC容器");
    17         
    18         //2.从IOC容器中获取Bean实例
    19         System.out.println("开始从IOC容器中获取Bean实例");
    20         Persion p2 = (Persion) ext.getBean("persionService");
    21         System.out.println("结束从IOC容器中获取Bean实例");
    22         
    23         //3.调用实例对象的方法
    24         System.out.println("开始调用实例对象的方法");
    25         System.out.println(p2.toString());
    26         System.out.println("结束调用实例对象的方法");
    27     }
    28 
    29 }

    我们在之前代码的每一行前后都加了打印,目的就是想看看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 http://www.springframework.org/schema/beans/spring-beans.xsd">
        <!-- 配置Bean
        class:bean的全类名,通过反射的方式在IOC容器中创建Bean,所以要求Bean中必须有 无参的构造函数
        id:表示容器的bean,id是唯一的,即在这个xml文件中要唯一 -->
        <bean id="persionService" class="com.study.entity.Persion">
        <property name="name" value="xiaozhang"></property>
        </bean>
    </beans>

    输出的结果如下:

    开始创建Spring的IOC容器
    三月 05, 2020 8:28:51 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1dd92fe2: startup date [Thu Mar 05 20:28:51 CST 2020]; root of context hierarchy
    三月 05, 2020 8:28:51 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [applicationContext.xml]
    Persion's Contructor....
    setName:xiaozhang
    结束创建Spring的IOC容器
    开始从IOC容器中获取Bean实例
    结束从IOC容器中获取Bean实例
    开始调用实例对象的方法
    Persion [name=xiaozhang, age=null]
    结束调用实例对象的方法

    可以看到,我们在创建Spring的IOC容器的时候,就会创建Persion的实例对象,并且给对象的属性赋值。

    也就是说,只要容器启动了,容器内就已经存在xml中配置的实例对象,所以我们可以通过getBean的方式去获取Bean。

     我们讲一下IOC和DI。IOC(Inversion of Control):其思想是翻转资源获取的方向,传统的资源查找方式要求组件向容器发起请求查找资源。作为回应,容器适当的时候返回资源。而应用了IOC之后,则是容器主动的将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源。这种行为也被称为查找的被动形式。

    DI(Dependency Injection)组件以一些预先定义好的方式(如setter方法)接受来自容器的资源注入。

    package logan.spring.study;
    
    public class HelloWorld {
        
        private String name;
        
        public void setName2(String name){
            System.out.println("setName: "+ name);
            this.name = name;
        }
        public void hello(){
            System.out.println("hello: " + name);
        }
        public HelloWorld(){
            System.out.println("HelloWorld's Constructor...");
        }
    
    }
    package logan.spring.study;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //1.创建Spring的IOC容器对象
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            //2.从 IOC容器中获取Bean实例
            HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello");
            //3.调用hello方法
            System.out.println(helloWorld);
    
        }
    
    }

    applicationContext

    <?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
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数
        id:表示容器的bean,id唯一 -->
        <bean id="hello" class="logan.spring.study.HelloWorld">
        </bean>
    
    </beans>

    输出结果

    五月 18, 2017 8:51:39 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Thu May 18 20:51:39 CST 2017]; root of context hierarchy
    五月 18, 2017 8:51:39 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [applicationContext.xml]
    HelloWorld's Constructor...
    logan.spring.study.HelloWorld@48eff760

    ApplicationContext本身是一个容器

    ApplicationContext的主要实现类:

    ClassPathXmlApplicationContext():从类路径下加载配置文件

    FileSystemXmlApplicationContext:从文件系统加载配置文件

    ConfigurableAppliactionContext扩展于ApplicationContext,新增加两个主要方法,refresh()和close(),让ApplicationContext具有启动,刷新和关闭上下文的功能。

    ApplicationContext在初始化上下文时就实例化所有单例的Bean。

    WebApplicationContext是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作。

    获取bean还可以用一下方式:

    package logan.spring.study;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //1.创建Spring的IOC容器对象
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            //2.从 IOC容器中获取Bean实例
            HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello");
            HelloWorld hello = ctx.getBean(HelloWorld.class);
            //3.调用hello方法
            System.out.println(hello);
    
        }
    
    }

    这样做有缺点,就是如果在配置文件里面配置两个Bean,它就会报错。

    <?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
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数
        id:表示容器的bean,id唯一 -->
        <bean id="hello" class="logan.spring.study.HelloWorld">
        </bean>
        
        <bean id="hello2" class="logan.spring.study.HelloWorld">
        </bean>
    
    </beans>

    这样就会报错

    Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'logan.spring.study.HelloWorld' available: expected single matching bean but found 2: hello,hello2
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1093)
        at logan.spring.study.Main.main(Main.java:14)

    所以在利用类型返回IOC容器中的Bean,但是要求IOC容器中必须只能有一个该类型的Bean。

  • 相关阅读:
    harbor docker
    dns服务器
    k8s
    frps
    svn 搭建
    phpstrom 破解 转载https://www.jianshu.com/p/e71361b3bfee
    公开课
    k8s
    rsync各种备份
    定时任务
  • 原文地址:https://www.cnblogs.com/LoganChen/p/6869862.html
Copyright © 2020-2023  润新知