首页 > 其他分享 >Spring学习笔记(三)——Spring依赖注入

Spring学习笔记(三)——Spring依赖注入

时间:2022-08-28 23:44:32浏览次数:44  
标签:依赖 name Grade Spring 笔记 id Student gradeId public

1.Spring Bean属性注入的几种方式

1.1构造函数注入

使用构造函数实现属性注入大致步骤如下:

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

示例如下:

Grade(Bean)类代码如下:

复制代码
public class Grade {
    private static final Log LOGGER = LogFactory.getLog(Grade.class);
    private Integer gradeId;
    private String gradeName;
    public Grade(Integer gradeId, String gradeName) {
        LOGGER.info("正在执行 Course 的有参构造方法,参数分别为:gradeId=" + gradeId + ",gradeName=" + gradeName);
        this.gradeId = gradeId;
        this.gradeName = gradeName;
    }
    @Override
    public String toString() {
        return "Grade{" +
                "gradeId=" + gradeId +
                ", gradeName='" + gradeName + '\'' +
                '}';
    }
}
复制代码

Student(Bean)类代码如下:

这里可以说Student类依赖于Grade类。

复制代码
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("正在执行 Course 的有参构造方法,参数分别为:id=" + id + ",name=" + name + ",grade=" + grade);
        this.id = id;
        this.name = name;
        this.grade = grade;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", grade=" + grade +
                '}';
    }
}
复制代码

Beans.xml代码如下:

注意直接类型用value,自定义的引用类型用ref。

复制代码
<?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="net.biancheng.c.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="net.biancheng.c.Grade">
        <constructor-arg name="gradeId" value="4"></constructor-arg>
        <constructor-arg name="gradeName" value="四年级"></constructor-arg>
    </bean>
</beans>
复制代码

主类代码如下:

复制代码
public class MainApp {
    private static final Log LOGGER = LogFactory.getLog(MainApp.class);
    public static void main(String[] args) {
        //获取 ApplicationContext 容器
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        //获取名为 student 的 Bean
        Student student = context.getBean("student", Student.class);
        //通过日志打印学生信息
        LOGGER.info(student.toString());
    }
}
复制代码

控制台输出如下:

复制代码
十二月 16, 2021 4:38:42 下午 net.biancheng.c.Grade <init>
信息: 正在执行 Course 的有参构造方法,参数分别为:gradeId=4,gradeName=四年级
十二月 16, 2021 4:38:42 下午 net.biancheng.c.Student <init>
信息: 正在执行 Course 的有参构造方法,参数分别为:id=2,name=李四,grade=Grade{gradeId=4, gradeName='四年级'}
十二月 16, 2021 4:38:42 下午 net.biancheng.c.MainApp main
信息: Student{id=2, name='李四', grade=Grade{gradeId=4, gradeName='四年级'}}
复制代码

1.2 setter注入

使用 setter 注入的方式进行属性注入,大致步骤如下:

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

示例如下:

Student(Bean)类代码如下:

复制代码
public class Student {
    private static final Log LOGGER = LogFactory.getLog(Student.class);
    private int id;
    private String name;
    private Grade grade;
    //无参构造方法,在没有其他带参构造方法的情况下,可以省略
    public Student() {
    }
    //id 属性的 setter 方法
    public void setId(int id) {
        LOGGER.info("正在执行 Student 类的 setId() 方法…… ");
        this.id = id;
    }
    //name 属性的 setter 方法
    public void setName(String name) {
        LOGGER.info("正在执行 Student 类的 setName() 方法…… ");
        this.name = name;
    }
    public void setGrade(Grade grade) {
        LOGGER.info("正在执行 Student 类的 setGrade() 方法…… ");
        this.grade = grade;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", grade=" + grade +
                '}';
    }
}
复制代码

Grade(Bean)类代码如下:

复制代码
public class Grade {
    private static final Log LOGGER = LogFactory.getLog(Grade.class);
    private Integer gradeId;
    private String gradeName;
    /**
     * 无参构造函数
     * 若该类中不存在其他的带参构造函数,则这个默认的无参构造函数可以省略
     */
    public Grade() {
    }
    public void setGradeId(Integer gradeId) {
        LOGGER.info("正在执行 Grade 类的 setGradeId() 方法…… ");
        this.gradeId = gradeId;
    }
    public void setGradeName(String gradeName) {
        LOGGER.info("正在执行 Grade 类的 setGradeName() 方法…… ");
        this.gradeName = gradeName;
    }
    @Override
    public String toString() {
        return "Grade{" +
                "gradeId=" + gradeId +
                ", gradeName='" + gradeName + '\'' +
                '}';
    }
}
复制代码

Beans.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-3.0.xsd">
    <bean id="student" class="net.biancheng.c.Student">
        <!--使用 property 元素完成属性注入
            name: 类中的属性名称,例如 id,name
            value: 向属性注入的值 例如 学生的 id 为 1,name 为张三
        -->
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
        <property name="grade" ref="grade"></property>
    </bean>
    <bean id="grade" class="net.biancheng.c.Grade">
        <property name="gradeId" value="3"></property>
        <property name="gradeName" value="三年级"></property>
    </bean>
</beans>
复制代码

Main方法如上,输出信息一致。

1.3 短命名空间注入

本质上是对前两种方法的一个简写形式。

我们在通过构造函数或 setter 方法进行属性注入时,通常是在 <bean> 元素中嵌套 <property> 和 <constructor-arg> 元素来实现的。这种方式虽然结构清晰,但书写较繁琐。
Spring 框架提供了 2 种短命名空间,可以简化 Spring 的 XML 配置,如下表。

 p命名空间注入

p 命名空间是 setter 方式属性注入的一种快捷实现方式。通过它,我们能够以 bean 属性的形式实现 setter 方式的属性注入,而不再使用嵌套的 <property> 元素,以实现简化 Spring 的 XML 配置的目的。
首先我们需要在配置文件的 <beans> 元素中导入以下 XML 约束。

xmlns:p="http://www.springframework.org/schema/p"

在导入 XML 约束后,我们就能通过以下形式实现属性注入。

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

Bean类省略了,看一下Beans.xml的代码写法:

复制代码
<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="employee" class="net.biancheng.c.Employee" p:empName="小李" p:dept-ref="dept" p:empNo="22222"></bean>
    <bean id="dept" class="net.biancheng.c.Dept" p:deptNo="1111" p:deptName="技术部"></bean>
</beans>
复制代码

c命名空间注入

c 命名空间是构造函数注入的一种快捷实现方式。通过它,我们能够以 <bean> 属性的形式实现构造函数方式的属性注入,而不再使用嵌套的 <constructor-arg> 元素,以实现简化 Spring 的 XML 配置的目的。
首先我们需要在配置文件的 <beans> 元素中导入以下 XML 约束。

xmlns:c="http://www.springframework.org/schema/c"

在导入 XML 约束后,我们就能通过以下形式实现属性注入。

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

Beans.xml中代码如下:

<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="employee" class="net.biancheng.c.Employee" c:empName="小胡" c:dept-ref="dept" c:empNo="999"></bean>
    <bean id="dept" class="net.biancheng.c.Dept" c:deptNo="2222" c:deptName="测试部"></bean>
</beans>

2.Spring注入内部Beans

之前我们在处理类的依赖时(也就是一个类中保持有另外一个类的对象),使用的是ref属性进行链接到依赖类的id,我们还可以使用内部注入的方式来完成依赖注入。

来看一个代码示例:

TextEditor类代码文件(Bean):

public class TextEditor {
   private SpellChecker spellChecker;
   // a setter method to inject the dependency.
   public void setSpellChecker(SpellChecker spellChecker) {
      System.out.println("Inside setSpellChecker." );
      this.spellChecker = spellChecker;
   }  
   // a getter method to return spellChecker
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

下面是另一个依赖的类文件 SpellChecker.java 内容:

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling(){
      System.out.println("Inside checkSpelling." );
   }   
}

主文件内容如下:

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      TextEditor te = (TextEditor) context.getBean("textEditor");
      te.spellCheck();
   }
}

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

   <!-- Definition for textEditor bean using inner bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
      <property name="spellChecker">
         <bean id="spellChecker" class="com.tutorialspoint.SpellChecker"/>
       </property>
   </bean>

3.Spring注入集合

你已经看到了如何使用 value 属性来配置基本数据类型和在你的 bean 配置文件中使用<property>标签的 ref 属性来配置对象引用。这两种情况下处理奇异值传递给一个 bean。

现在如果你想传递多个值,如 Java Collection 类型 List、Set、Map 和 Properties,应该怎么做呢。

 示例如下:

这里是 JavaCollection.java 文件的内容:

public class JavaCollection {
   List addressList;
   Set  addressSet;
   Map  addressMap;
   Properties addressProp;

   public void setAddressList(List addressList) {
      this.addressList = addressList;
   }

   public List getAddressList() {
      System.out.println("List Elements :"  + addressList);
      return addressList;
   }

   public void setAddressSet(Set addressSet) {
      this.addressSet = addressSet;
   }

   public Set getAddressSet() {
      System.out.println("Set Elements :"  + addressSet);
      return addressSet;
   }

   public void setAddressMap(Map addressMap) {
      this.addressMap = addressMap;
   }  

   public Map getAddressMap() {
      System.out.println("Map Elements :"  + addressMap);
      return addressMap;
   }

   public void setAddressProp(Properties addressProp) {
      this.addressProp = addressProp;
   } 

   public Properties getAddressProp() {
      System.out.println("Property Elements :"  + addressProp);
      return addressProp;
   }
}

主方法内容:

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");
      JavaCollection jc=(JavaCollection)context.getBean("javaCollection");
      jc.getAddressList();
      jc.getAddressSet();
      jc.getAddressMap();
      jc.getAddressProp();
   }
}

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

   <!-- Definition for javaCollection -->
   <bean id="javaCollection" class="com.tutorialspoint.JavaCollection">

      <!-- results in a setAddressList(java.util.List) call -->
      <property name="addressList">
         <list>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
         </list>
      </property>

      <!-- results in a setAddressSet(java.util.Set) call -->
      <property name="addressSet">
         <set>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
        </set>
      </property>

      <!-- results in a setAddressMap(java.util.Map) call -->
      <property name="addressMap">
         <map>
            <entry key="1" value="INDIA"/>
            <entry key="2" value="Pakistan"/>
            <entry key="3" value="USA"/>
            <entry key="4" value="USA"/>
         </map>
      </property>

      <!-- results in a setAddressProp(java.util.Properties) call -->
      <property name="addressProp">
         <props>
            <prop key="one">INDIA</prop>
            <prop key="two">Pakistan</prop>
            <prop key="three">USA</prop>
            <prop key="four">USA</prop>
         </props>
      </property>

   </bean>

</beans>

上面注入的都是基本元素,如果集合中存储的是引用类型元素应该如何写Beans.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-3.0.xsd">

   <!-- Bean Definition to handle references and values -->
   <bean id="..." class="...">

      <!-- Passing bean reference  for java.util.List -->
      <property name="addressList">
         <list>
            <ref bean="address1"/>
            <ref bean="address2"/>
            <value>Pakistan</value>
         </list>
      </property>

      <!-- Passing bean reference  for java.util.Set -->
      <property name="addressSet">
         <set>
            <ref bean="address1"/>
            <ref bean="address2"/>
            <value>Pakistan</value>
         </set>
      </property>

      <!-- Passing bean reference  for java.util.Map -->
      <property name="addressMap">
         <map>
            <entry key="one" value="INDIA"/>
            <entry key ="two" value-ref="address1"/>
            <entry key ="three" value-ref="address2"/>
         </map>
      </property>

   </bean>

</beans>

 

 

 

 

 

 

标签:依赖,name,Grade,Spring,笔记,id,Student,gradeId,public
From: https://www.cnblogs.com/worthmove/p/16634473.html

相关文章

  • Linux学习笔记3——vi和vim编辑器
    Linux学习笔记3——vi和vim编辑器一、vi和vim编辑器:vi和vim是Linux中的文本编辑器,用来在Linux中创建、查看或编辑文本文件,就好像window系统的记事本一样,但是不能查看图片......
  • Linux学习笔记2——目录结构
    Linux学习笔记2——目录结构一、Linux的目录结构:Linux只有一个根目录:/层级式的目录结构:1)root:该目录为系统管理员目录,root是具有超级权限的用户。2)bin->usr/bin:存放系......
  • HCIA学习笔记二十四:单臂路由实现VLAN间路由
    一、VLAN的缺点• VLAN隔离了二层广播域,也就严格地隔离了各个VLAN之间的任何流量,分属于不同VLAN的用户不能互相通信。二、使用VLANTrunking• 二层交换机和路由器之......
  • Mysql的视图使用场景笔记
    mysql的视图本质上就是一条预定义的联表查询sql语句当设计一个数据库模型的时候,各个数据表模型之间的关系在一定程度上是独立的,即使两个数据模型表之间存在一对多或者多对......
  • 快速搭建 SpringCloud Alibaba Nacos 配置中心!
    SpringCloudAlibaba是阿里巴巴提供的一站式微服务开发解决方案,目前已被SpringCloud官方收录。而Nacos作为SpringCloudAlibaba的核心组件之一,提供了两个非常重......
  • Python学习笔记(十一)-- Django API RESTful
    1.Django restframework之序列化https://www.cnblogs.com/midworld/p/11380194.html  2.写API的三个重点(1)路由;(2)视图类(提供给用户访问相当于原来的视图函数);(3)序列化......
  • Swagger2—整合SpringBoot
    一、Swagger用于生成服务器接口的规范文档的工具,并且能够对接口进行测试的工具1.1作用生成接口说明文档对接口进行测试1.2整合添加依赖(Swagger2、SwaggerUI)......
  • spring AOP
    springaop怎么用与实现原理:https://blog.csdn.net/u012098021/article/details/116802329 springaop:定义advisoradvisor:Pointcut与 Advice Advice:增强方法Poi......
  • 【笔记】Oracle 窗口函数
    Oracle窗口函数简单来说,窗口函数是分析函数的一种,通常可以理解成over()函数构成:函数名①()over(partitionby分组的列名orderby排序的列名XXX)XXX是指特殊使用的......
  • Spring学习笔记(二)
    1.SpringIOC1.1控制反转IOC在传统的Java应用中,一个类想要调用另一个类中的属性或方法,通常会先在其代码中通过newObject()的方式将后者的对象创建出来,然后才能实现......