Bean属性注入

举报
CoderX 发表于 2022/04/06 13:33:47 2022/04/06
【摘要】 Bean属性注入​ 将属性或是一个对象(Bean)注入到Bean的过程称为Bean属性注入。Spring主要通过2中方式实现属性注入:构造函数注入Setter注入(设值注入) 构造函数注入​ 可以通过Bean的带参构造函数,来实现Bean的属性注入。大致步骤:在Bean中添加一个有参构造函数,构造函数内的每一个参数代表需要注入的属性在Spring的XML配置文件中,通...

Bean属性注入

​ 将属性或是一个对象(Bean)注入到Bean的过程称为Bean属性注入。Spring主要通过2中方式实现属性注入:

  • 构造函数注入
  • Setter注入(设值注入)

构造函数注入

​ 可以通过Bean的带参构造函数,来实现Bean的属性注入。大致步骤:

  1. 在Bean中添加一个有参构造函数,构造函数内的每一个参数代表需要注入的属性
  2. 在Spring的XML配置文件中,通过<beans>及其子元素<bean>对Bean进行定义
  3. 在<bean>元素内使用<construtor-arg>元素,对构造函数内的属性进行赋值,Bean的构造函数内有多少参数,就要使用多少了<construtor-arg>元素
package org.example;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Grade {
    private static final Log LOGGER= LogFactory.getLog(Grade.class);
    private int gradeId;
    private String gradeNum;


    public Grade( int gradeId,String gradeNum) {
        LOGGER.info("正在执行Grade的带参构造方法");
        this.gradeId = gradeId;
        this.gradeNum = gradeNum;
    }

    @Override
    public String toString() {
        return "Grade{" +
                "gradeId=" + gradeId +
                ", gradeNum='" + gradeNum + '\'' +
                '}';
    }
}

package org.example;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Student {
    private static final Log LOGGER= LogFactory.getLog(Student.class);
    private int id;
    private String name;
    private Grade grade;

    public Student(int id, String name, Grade grade) {
        LOGGER.info("正在执行Student的带参方法");
        this.id = id;
        this.name = name;
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", grade=" + grade +
                '}';
    }
}

package org.example;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class App{
    private static final Log LOGGER = LogFactory.getLog(App.class);
    public static void main( String[] args ){
        //创建上下文对象,读取配置文件  bean工厂
        ApplicationContext classPathContext=new ClassPa
       
       Student stuBean=classPathContext.getBean("student",Student.class);
        LOGGER.info(stuBean.toString());
    }
}

<?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-3.0.xsd">

 

    <bean id="student" class="org.example.Student">
        <constructor-arg name="id" value="2"></constructor-arg>
        <constructor-arg name="name" value="李四"></constructor-arg>
        <constructor-arg name="grade" ref="grade"></constructor-arg>
    </bean>

    <bean id="grade" class="org.example.Grade">
        <constructor-arg name="gradeId" value="4"></constructor-arg>
        <constructor-arg name="gradeNum" value="四年级"></constructor-arg>
    </bean>

</beans>

setter注入

在Spring实例化Bean的过程中,IoC容器首先会调用默认的构造方法(无参构造方法)实例化Bean(Java对象),然后通过Java反射机制调用这个Bean的setter方法,将属性注入到Bean中。大致步骤:

  • 在Bean中提供一个默认的无参构造函数(在没有其他带参构造函数的情况下,可以省略),并为所有需要注入的属性提供一个setter方法。
  • 在Spring的XML配置文件中,使用<beans>及其子元素<bean>对Bean进行定义
  • 在<bean>元素内使用<property>元素对各个属性进行赋值
package org.example;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Student {
    private static final Log LOGGER= LogFactory.getLog(Student.class);
    private int id;
    private String name;
    private Grade grade;

    //无参构造,没有其他带参构造的话可以省略
    public Student() {
    }

    public Student(int id, String name, Grade grade) {
        LOGGER.info("正在执行Student的带参方法");
        this.id = id;
        this.name = name;
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", grade=" + grade +
                '}';
    }

    public void setId(int id) {
        LOGGER.info("正在执行 Student 类的 setId() 方法…… ");
        this.id = id;
    }

    public void setName(String name) {
        LOGGER.info("正在执行 Student 类的 setName() 方法…… ");
        this.name = name;
    }

    public void setGrade(Grade grade) {
        LOGGER.info("正在执行 Student 类的 setGrade() 方法…… ");
        this.grade = grade;
    }
}

package org.example;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Grade {
    private static final Log LOGGER= LogFactory.getLog(Grade.class);
    private Integer gradeId;
    private String gradeNum;

    //无参构造,没有其他带参构造可以省略
    public Grade() {
    }

    public Grade(Integer gradeId, String gradeNum) {
        LOGGER.info("正在执行Grade的带参构造方法");
        this.gradeId = gradeId;
        this.gradeNum = gradeNum;
    }

    @Override
    public String toString() {
        return "Grade{" +
                "gradeId=" + gradeId +
                ", gradeNum='" + gradeNum + '\'' +
                '}';
    }

    public void setGradeId(Integer gradeId) {
        LOGGER.info("正在执行 Grade 类的 setGradeId() 方法…… ");
        this.gradeId = gradeId;
    }

    public void setGradeNum(String gradeNum) {
        LOGGER.info("正在执行 Grade 类的 setGradeName() 方法…… ");
        this.gradeNum = gradeNum;
    }
}

package org.example;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;


public class App{
    private static final Log LOGGER = LogFactory.getLog(App.class);
    public static void main( String[] args ){
        //创建上下文对象,读取配置文件  bean工厂
        ApplicationContext classPathContext=new ClassPathXmlApplicationContext("beans.xml");
        //通过构造方法创造bean
        Student stuBean=classPathContext.getBean("student",Student.class);
        LOGGER.info(stuBean.toString());
        //通过Setter方法创造bean
       Student stuBean1=classPathContext.getBean("stuSetter",Student.class);
        LOGGER.info(stuBean.toString());
    }
}

<?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-3.0.xsd">

    <!--使用带参构造方法注入-->
    <bean id="student" class="org.example.Student">
        <constructor-arg name="id" value="2"></constructor-arg>
        <constructor-arg name="name" value="李四"></constructor-arg>
        <constructor-arg name="grade" ref="grade"></constructor-arg>
    </bean>

    <bean id="grade" class="org.example.Grade">
        <constructor-arg name="gradeId" value="4"></constructor-arg>
        <constructor-arg name="gradeNum" value="四年级"></constructor-arg>
    </bean>
    <!--Setter注入-->
    <bean id="stuSetter" class="org.example.Student">
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
        <property name="grade" ref="grade"></property>
    </bean>
    <bean id="gradeSetter" class="org.example.Grade">
        <property name="gradeId" value="3"></property>
        <property name="gradeNum" value="三年级"></property>
    </bean>

</beans>

短命名空间注入

​ Spring框架提供了2种短命名空间来简化Spring的XML配置:

短命名空间 简化的 XML 配置 说明
p 命名空间 <bean> 元素中嵌套的 <property> 元素 是 setter 方式属性注入的一种快捷实现方式
c 命名空间 <bean> 元素中嵌套的 <constructor> 元素 是构造函数属性注入的一种快捷实现方式

p命名空间注入

p命名空间注入是setter注入的快捷方式

  1. 在配置文件的<beans>元素中导入XML约束

    xmlns:p="http://www.springframework.org/schema/p"
    
  2. 导入XML约束后,可以通过以下形式实现注入

    <bean id="Bean 唯一标识符" class="包名+类名" p:普通属性="普通属性值" p:对象属性-ref="对象的引用"></bean>
    

在使用p命名空间注入依赖时,要注意:

  • Java类中必须有setter方法
  • Java 类中必须有无参构造器(类中不包含任何带参构造函数的情况,无参构造函数默认存在);
  • 在使用 p 命名空间实现属性注入前,XML 配置的 <beans> 元素内必须先导入 p 命名空间的 XML 约束。

c命名空间注入

c命名空间注入是构造函数的快捷实现方式.

  1. 在配置文件<beans>元素中导入XML约束

    xmlns:c="http://www.springframework.org/schema/c"
    
  2. 导入XML约束后,可以通过以下形式实现属性注入

    <bean id="Bean 唯一标志符" class="包名+类名" c:普通属性="普通属性值" c:对象属性-ref="对象属性值"></bean>
    

在使用c命名空间注入依赖时,要注意:

  • Java类中必须包含对应的带参构造器;
  • 使用c命名空间实现属性注入前,XML配置的<beans>必须先导入c命名空间的XML约束

短命名空间注入示例:

package org.demo2;

/**
 * 部门类
 */
public class Dept {
    private  String deptNo;
    private String deptName;
   //使用setter注入或p命名空间注入,需要有无参构造,有其他带参构造不会默认存在
    public Dept() {
    }

    //c命名空间注入 / 构造函数注入constructor-arg
    public Dept(String deptNo, String deptName) {
        this.deptNo = deptNo;
        this.deptName = deptName;
    }

    //p命名空间注入 setter注入 property
    public void setDeptNo(String deptNo) {
        this.deptNo = deptNo;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "deptNo='" + deptNo + '\'' +
                ", deptName='" + deptName + '\'' +
                '}';
    }
}

package org.demo2;

/**
 * 员工类
 */
public class Employee {
    private String empNo;
    private String empName;
    private Dept dept;

    //使用setter注入或p命名空间注入,需要有无参构造,有其他带参构造不会默认存在
    public Employee() {
    }
    //c命名空间注入 / 构造函数注入constructor-arg
    public Employee(String empNo, String empName, Dept dept) {
        this.empNo = empNo;
        this.empName = empName;
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "empNo='" + empNo + '\'' +
                ", empName='" + empName + '\'' +
                ", dept=" + dept +
                '}';
    }

    //p命名空间注入 setter注入 property
    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }


}

package org.demo2;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    private static final Log LOGGER = LogFactory.getLog(MainApp.class);
    public static void main(String[] args) {
        //获取 ApplicationContext 容器
        ApplicationContext context=new ClassPathXmlApplicationContext("demo2beans.xml");
       //获取 p命名空间注入 的 Bean
        Employee pEmp = context.getBean("pEmp", Employee.class);
        //获取 c命名空间注入 的 Bean
        Employee cEmp = context.getBean("cEmp",Employee.class);
        //通过日志打印信息
        LOGGER.info(pEmp.toString());
        LOGGER.info(cEmp.toString());
    }
}

<?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:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <!--p命名空间注入-->
    <bean id="pEmp" class="org.demo2.Employee" p:empName="P小李" p:empNo="2222" p:dept-ref="pDept"></bean>
    <bean id="pDept" class="org.demo2.Dept" p:deptName="开发部" p:deptNo="1"></bean>
    <!--c命名空间注入-->
    <bean id="cEmp" class="org.demo2.Employee" c:empName="C小王" c:empNo="1111" c:dept-ref="cDpet"></bean>
    <bean id="cDpet" class="org.demo2.Dept" c:deptName="运维部" c:deptNo="2"></bean>
</beans>
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。