Spring之通过XML装配Bean

IOC简介

IOC思想基于IOC容器完成,IOC容器底层就是对象工厂。
Spring提供IOC容器实现两种方式(两个接口):

  • BeanFactory:IOC容器基本实现,是spring内部使用的接口,不提供给开发人员使用
    • 加载配置文件时,不会主动创建对象,在使用对象时才会创建
  • ApplicationContext:BeanFactory的子接口,提供更多更强大的功能,供开发人员使用
    • 加载配置文件时, 完成对象创建
    • 主要有是个实现类
      • ClassPathXmlApplicationContext
      • FileSystemApplicationContext

IOC操作之bean管理

什么是bean管理?

bean管理就是两个操作

  • 创建对象
  • 注入属性

bean管理操作两种方式:

  • 基于xml配置文件方式实现
  • 基于注解方式实现

基于xml方式装配Bean

在Spring刚出现的时候,XML是描述配置的主要方式,但随着强大的自动化配置和基于Java的配置出现,XML已经不再是第一选择了。

对象创建

在spring配置文件中,使用bean标签,添加对应属性,即可实现对象创建

<bean id="user" class="com.happy.learn.model.User"/>
  • id属性:唯一标识
  • class属性:要创建的对象全路径
  • name属性:可以使用特殊符号,其他同id属性,基本不使用了

如上创建对象时,默认执行无参构造方法。

通过xml方式注入属性

DI:依赖注入,是IOC的一种具体实现,就是注入属性

使用set方法注入
public class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
<bean id="user" class="com.happy.learn.model.User">
    <property name="age" value="12"/>
    <property name="name" value="旺财"/>
</bean>
ClassPathXmlApplicationContext xmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");
        User user = xmlApplicationContext.getBean("user", User.class);
        System.out.println(user);
 
输出结果为:User{name='旺财', age=12}
使用有参构造函数注入
public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
<bean id="student" class="com.happy.learn.model.Student">
    <constructor-arg name="age" value="34"/>
    <constructor-arg name="name" value="大强"/>
    <!--<constructor-arg index="0" value="34"/>
    <constructor-arg index="1" value="大强"/>-->
</bean>
Student student = xmlApplicationContext.getBean("student", Student.class);
System.out.println(student);
输出结果为:Student{name='大强', age=34}

p名称空间注入

简化基于xml配置方式,了解即可

在beans.xml文件中,声明命名空间
在这里插入图片描述

<bean id="user2" class="com.happy.learn.model.User" p:age="12" p:name="旺财"/>

注入其他类型属性

字面量

null值

<property name="name" value=""/>  User{name='', age=12}
<property name="name">
    <null/><!--User{name='null', age=12}-->
</property>

插入特殊符号
a. 符号转义,eg. &lt; &gt;
b. 使用CDATA

<property name="address">
   <value><![CDATA[<<北京市>>]]></value>
</property>
输出结果为:User{name='孙大圣', age=12, address='<<北京市>>'}
注入外部bean

a. 创建两个类,service和dao

public interface UserDao {
    public void add();
}

public class UserDaoImpl implements UserDao {
    @Override
    public void add() {
        System.out.println("userDao add....");
    }
}

public class UserService {
    public void add(){
        System.out.println("userService add...");
    }
}

b. 在service中,调用dao方法

public class UserService {

    //    声明userDao,提供set方法
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void add() {
        System.out.println("userService add...");
        userDao.add();
    }

}

c. 在spring配置文件中进行配置

<bean id="userService" class="com.happy.learn.service.UserService">
   <property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.happy.learn.dao.UserDaoImpl"/>
注入内部bean
  1. 一对多 eg. 部门与员工
  2. 在实体类中表示一对多关系
public class Department {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Department{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class Employee {
    private String name;
    private String gender;
    private Department department;

    public void setName(String name) {
        this.name = name;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", department=" + department +
                '}';
    }
}
  1. 在spring配置文件中进行相关配置
<bean id="employee" class="com.happy.learn.model.Employee">
    <property name="name"value="张三"/>
    <property name="gender" value=""/>
    <!-- 可以使用内部bean -->
    <property name="department">
        <bean id="department" class="com.happy.learn.model.Department">
            <property name="name" value="研发部"/>
        </bean>
    </property>
</bean>
输出结果为:Employee{name='张三', gender='男', department=Department{name='研发部'}}
注入内部bean之级联赋值
第一种写法
<bean id="employee" class="com.happy.learn.model.Employee">
    <property name="name" value="张三"/>
    <property name="gender" value=""/>
    <property name="department" ref="department"/>
</bean>

<bean id="department" class="com.happy.learn.model.Department">
    <property name="name" value="研发部"/>
</bean>
第二种写法

添加get方法:

public Department getDepartment() {
   return department;
}
<bean id="employee" class="com.happy.learn.model.Employee">
    <property name="name" value="张三"/>
    <property name="gender" value=""/>
    <property name="department" ref="department"/>
    <property name="department.name" value="总裁办"/>
</bean>

<bean id="department" class="com.happy.learn.model.Department">
    <property name="name" value="财务部"/>
</bean>
Employee{name='张三', gender='男', department=Department{name='总裁办'}}

通过xml注入集合属性

  1. 注入数组类型属性
  2. 注入List集合类型属性
  3. 注入Map集合类型属性
  4. 注入Set集合类型属性
public class Teacher {
    private String[] course;
    private List<String> list;
    private Map<String, String> map;
    private Set<String> set;

    public void setCourse(String[] course) {
        this.course = course;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "course=" + Arrays.toString(course) +
                ", list=" + list +
                ", map=" + map +
                ", set=" + set +
                '}';
    }
}
<bean id="teacher" class="com.happy.learn.model.Teacher">
    <property name="course">
        <array>
            <value>数学</value>
            <value>英语</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>张三</value>
            <value>李四</value>
        </list>
    </property>
    <property name="map">
        <map>
            <entry key="name" value="旺财"/>
            <entry key="age" value="12"/>
        </map>
    </property>
    <property name="set">
        <set>
            <value>篮球</value>
            <value>足球</value>
        </set>
    </property>
</bean>
Teacher{course=[数学, 英语], list=[张三, 李四], map={name=旺财, age=12}, set=[篮球, 足球]}

在集合中设置对象类型的值

private List<Student> students;

public void setStudents(List<Student> students) {
    this.students = students;
}
<property name="students">
    <list>
        <!--注入list集合,但值为对象-->
        <ref bean="s1"/>
        <ref bean="s2"/>
    </list>
</property>
<bean id="s1" class="com.happy.learn.model.Student">
    <constructor-arg name="age" value="34"/>
    <constructor-arg name="name" value="大强"/>
</bean>
<bean id="s2" class="com.happy.learn.model.Student">
    <constructor-arg name="age" value="18"/>
    <constructor-arg name="name" value="小明"/>
</bean>
Teacher{course=[数学, 英语], list=[张三, 李四], map={name=旺财, age=12}, set=[篮球, 足球], students=[Student{name='大强', age=34}, Student{name='小明', age=18}]}

把集合注入部分提取
在spring配置文件中引入名称空间util

<?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:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd">

</beans>
使用util标签完成集合注入提取
<!--  提取集合类型属性注入 以list为例  -->
<util:list id="courseList">
    <value>三国演义</value>
    <value>封神榜</value>
    <value>红楼梦</value>
    <value>西游记</value>
</util:list>
 <!--        <property name="list">-->
 <!--            <list>-->
 <!--                <value>张三</value>-->
 <!--                <value>李四</value>-->
 <!--            </list>-->
 <!--        </property>-->
 <property name="list" ref="courseList"/>

XML自动装配

通过autowire开启自动装配,有两个选项,分别为byNamebyType,区别如下:

  • byName: 按照属性名自动装配
  • byType: 根据属性类型自动装配,如果有多个同类型的bean,会报错
<bean id="emp" class="com.happy.learn.model.Employee" autowire="byName"/>
<bean id="department" class="com.happy.learn.model.Department"/>

FactoryBean

spring中有两种Bean,一种是普通Bean,另外一种就是FactoryBean

  • 普通Bean:在spring配置文件中,定义的类型就是返回的类型
  • 工厂Bean:在配置文件中Bean类型可以和返回的类型不一样

创建一个类,让这个类作为工厂Bean,实现FactoryBean接口
实现接口方法,在方法中定义返回Bean类型

public class MyFactoryBean implements FactoryBean<Student> {
    @Override
    public Student getObject() throws Exception {
        Student student = new Student("旺财", 12);
        return student;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}
<bean id="myFactoryBean" class="com.happy.learn.factory.MyFactoryBean"/>
输出结果为:Student{name='旺财', age=12}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值