2_基于XML管理Bean

2. 基于XML管理Bean

2.1 项目准备:

首先创建实体类User.java:

package com.lily.iocxml;

public class User {
    private String name;
    private Integer age;

    public void run(){
        System.out.println("run...");
    }
}

其次创建spring的配置文件bean.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">

</beans>

2.2 获取bean

2.2.1 根据id获取

由于id属性定义了bean的唯一标识,所以根据bean标签的id属性可以准确的获取到一个组件对象。

  • 首先在bean.xml进行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">
       <!-- user对象创建 -->
       <bean id="user" class="com.lily.iocxml.User"/>
    </beans>
    
  • 编写测试类获取对象进行验证:

    public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
            //根据id获取bean
            User user = (User)context.getBean("user");
            System.out.println("根据id获取bean:"+user);
        }
    

2.2.2 根据类型获取

  • 在上述的基础上:

    // 根据类型获取java bean对象
    User user = context.getBean(User.class);
    System.out.println(user);
    

2.2.3 根据id和类型获取

  • 在上述的基础上:

    // 根据id和类型获取Java bean对象
    User user = context.getBean("user", User.class);
    System.out.println(user);
    

2.3 依赖注入之set注入

  1. 首先创建学生类Student

    public class Book {
       private String bookName;
       private String bookAuthor;
    
        public Book() {
        }
    
        public Book(String bookName, String bookAuthor) {
            this.bookName = bookName;
            this.bookAuthor = bookAuthor;
        }
    
        public String getBookName() {
            return bookName;
        }
    
        public void setBookName(String bookName) {
            this.bookName = bookName;
        }
    
        public String getBookAuthor() {
            return bookAuthor;
        }
    
        public void setBookAuthor(String bookAuthor) {
            this.bookAuthor = bookAuthor;
        }
        
        @Override
        public String toString() {
            return "Book{" +
                    "bookName='" + bookName + '\'' +
                    ", bookAuthor='" + bookAuthor + '\'' +
                    '}';
        }
    }
    
  2. 在Spring配置文件中进行配置:

    <bean id="book" class="com.lily.iocxml.Book">
        <property name="bookName" value="Java development"/>
        <property name="bookAuthor" value="......."/>
    </bean>
    
  3. 进行测试:

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        Book book = context.getBean("book", Book.class);
        System.out.println(book.toString());
    }
    

2.4 依赖注入之构造器注入

  1. 在Spring配置文件中进行配置:

    <bean id="book" class="com.lily.iocxml.Book">
            <constructor-arg name="bookName" value="C++"/>
            <constructor-arg name="bookAuthor" value="++C"/>
    </bean>
    
  2. 进行测试:

    public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
            Book book = context.getBean("book", Book.class);
            System.out.println(book.toString());
    }
    

2.5 特殊值处理

  1. 字面量赋值

    <property name="bookName" value="张三"/>
    
  2. null值

    <bean id="book" class="com.lily.iocxml.Book">
            <property name="bookName">
                <null/>
            </property>
        </bean>
    </beans>
    
  3. xml实体(特殊符号->需要转义)

    <property name="bookAuthor" value="&lt;&gt;"/>
    
  4. CDATA区(XML特有的写法)

    <bean id="book" class="com.lily.iocxml.Book">
           <!--
               使用CDATA节(区):
               C代表的是Character,是文本、字符的含义,CDATA表示的是纯文本数据。
               XML解析器看到CDATA节就知道这里是纯文本,就不会当做XML标签进行解析。
               所以CDATA里面写什么符号都可以
           -->
           <property name="bookName">
               <value><![CDATA[ a<b ]]></value>
           </property>
       </bean>
    

2.6 为对象类型属性赋值

  1. 创建部门类:

    public class Dept {
       private String departName;
    
        public String getDepartName() {
            return departName;
        }
    
        public void setDepartName(String departName) {
            this.departName = departName;
        }
        
        public void info() {
            System.out.println("部门名称:" + departName);
        }
    }
    
  2. 创建员工类:

    public class Emp {
        private String eName;
        private Integer age;
        
        // 员工属于某个部门
        private Dept dept;
    
        public void work() {
            System.out.println(eName + "emp work..." + age);
        }
    
        public String geteName() {
            return eName;
        }
    
        public void seteName(String eName) {
            this.eName = eName;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    
    

2.6.1 引入外部bean(在当前类中定义的有其它类的对象)

  1. 首先在配置文件中进行如下配置:
<?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">

    <!-- 
        在员工对象里使用部门对象: 
        1. 创建两个对象:dept and emp.
        2. 在emp里面使用property标签引入dept的bean.
    -->
    <bean id="dept" class="com.lily.iocxml.Dept">
        <property name="departName" value="保安部"/>
    </bean>
    <bean id="emp" class="com.lily.iocxml.Emp">
        <property name="eName" value="张三"/>
        <property name="dept" ref="dept"/>
        <property name="age" value="1008611"/>
    </bean>
    
</beans>
  1. 创建测试类:
public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
       //员工对象
       Emp emp = context.getBean("emp", Emp.class);
       emp.work();
   }

2.6.2 引入内部bean

只是把需要使用的外部类对象创建步骤放到自身类对象创建的内部(里面):

<!-- 
        内部bean注入
    -->
    <bean id="emp2" class="com.lily.iocxml.Emp">
        <property name="eName" value="李四"/>
        <property name="age" value="10011"/>
        <!-- 内部bean -->
        <property name="dept">
            <bean id="dept2" class="com.lily.iocxml.Dept">
                <property name="departName" value="财务部"/>
            </bean>
        </property>
    </bean>

2.6.3 级联属性赋值

<!-- 级联赋值 -->
    <bean id="dept3" class="com.lily.iocxml.Dept">
        <property name="departName" value="技术研发部"/>
    </bean>
    
    <bean id="emp3" class="com.lily.iocxml.Emp">
        <property name="eName" value="lily"/>
        <property name="age" value="99"/>
		<!-- <property name="dept" ref="dept3"/>-->
        <property name="dept.departName" value="测试部"/>
    </bean>

2.7 为数组类型属性赋值

  1. 创建User类:

    public class User {
        private String name;
        private Integer age;
    
        private String[] loves;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String[] getLoves() {
            return loves;
        }
    
        public void setLoves(String[] loves) {
            this.loves = loves;
        }
    }
    
  2. 编配配置文件:

    <!-- 数字类型属性 -->
        <bean id="user" class="com.lily.iocxml.User">
            <property name="name" value="张三"/>
            <property name="age" value="99"/>
            <property name="loves">
                <array>
                    <value>唱</value>
                    <value>跳</value>
                    <value>rip</value>
                    <value>打篮球</value>
                </array>
            </property>
        </bean>
    
  3. 创建测试类:

    public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
            User user = context.getBean("user", User.class);
            String[] loves = user.getLoves();
            for(String elem:loves){
                System.out.println(elem);
            }
        }
    

2.8 为集合类型属性赋值

同上面的数组类型相似:

private List<String> loves;
public List<String> getLoves() {
    return loves;
}

public void setLoves(List<String> loves) {
    this.loves = loves;
}
<bean id="user" class="com.lily.iocxml.User">
        <property name="name" value="张三"/>
        <property name="age" value="99"/>
        <property name="loves">
            <list>
                <value>唱</value>
                <value>跳</value>
                <value>rip</value>
                <value>打篮球</value>
            </list>
        </property>
    </bean>

2.9 引入外部属性文件

  1. 创建外部依赖文件jdbc.properties:

    jdbc.user=root
    jdbc.password=root
    jdbc.url=mysql://localhost:3306/spring?serverTimezone=UTC
    jdbc.driver=com.mysql.cj.jdbc.Driver
    
  2. 引入外部文件(引用context名称空间)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!-- 引入外部属性文件 -->
        <context:property-placeholder location="classpath:jdbc.properties"/>
        <!-- 完成数据库连接池注入 -->
        <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.user}"/>
            <property name="password" value="${jdbc.password}"/>
            <property name="driverClassName" value="${jdbc.driver}"/>
        </bean>
    </beans>
    

2.10 bean的作用域

在Spring中通过配置bean标签的scope属性来指定bean的作用域范围,各取值含义如下:

  • singleton(默认):在IOC容器初始化时创建对象,在IOC容器中,这个bean对象始终为单实例。
  • prototype:在获取bean时创建实例,这个bean在IOC容器中有多个实例。

演示:

  1. 首先创建Order类:

    public class Order {
    
    }
    
  2. 创建bean.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"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="order" class="com.lily.iocxml.Order" scope="singleton">
    </bean>
    
    </beans>
    
  3. 进行测试:

    public class Main {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
            Order order1 = context.getBean("order", Order.class);
            Order order2 = context.getBean("order", Order.class);
            Order order3 = context.getBean("order", Order.class);
            System.out.println(order1);
            System.out.println(order2);
            System.out.println(order3);
        }
    }
    
  4. 结果如下:

    com.lily.iocxml.Order@212bf671
    com.lily.iocxml.Order@212bf671
    com.lily.iocxml.Order@212bf671
    
    Process finished with exit code 0
    
  5. 如果将作用域singleton改为prototype,测试结果如下:

    com.lily.iocxml.Order@214b199c
    com.lily.iocxml.Order@20d3d15a
    com.lily.iocxml.Order@2893de87
    
    Process finished with exit code 0
    

2.11 bean的生命周期

Bean的生命周期:

  1. bean对象创建
  2. 给Bean对象设置属性值
  3. bean的前置处理器(初始化前)
  4. bean对象的初始化
  5. bean的后置处理器(初始化后)
  6. bean对象就绪使用
  7. bean对象销毁(需要在配置bean时指定销毁方法)
  8. IOC容器关闭

2.12 FactoryBean

FactoryBean时Spring提供的一种整合第三方框架的常用机制,和普通的bean不同,配置一个FactoryBean类型的bean,在获取bean时得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值。通过这种机制,Spring可以帮助我们吧复杂组件创建的额详细过程给屏蔽起来,在整合第三方框架时经常用到。

  1. 创建相关代码:

    public class MyFactoryBean implements FactoryBean<User> {
    
        @Override
        public User getObject() throws Exception {
            return new User;
        }
    
        @Override
        public Class<?> getObjectType() {
            return User.class;
        }
    }
    
    public class User {
    }
    
  2. 创建配置文件

        <bean id="user" class="com.lily.factoryBean.MyFactoryBean"></bean>
    
  3. 测试:

    public class Main {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
            User user = (User) context.getBean("user");
            System.out.println(user);
        }
    }
    

2.13 基于xml自动装配

自动装配:根据给定的策略,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类类型或接口类型属性赋值。

posted @ 2024-03-03 17:50  LilyFlower  阅读(1)  评论(0编辑  收藏  举报