• Spring中Setter注入详解


    目录

    一、setter注入是什么

    二、setter注入详解

    三、JDK内置类型注入方式

    3.1 数组类型

    3.2 set集合类型

    3.3 list集合

    3.4 map集合

    3.5 properties类型

    四、用户自定义类型


    一、setter注入是什么

    书接上回,我们发现在Spring配置文件中为类对象的属性赋值时,是Spring通过调用类中的setter方法。接下要就通过代码的形式来具体分析

    1)此时将Person类中的setter方法加入打印语句,如果使用Spring注入的时候进行了打印说明Spring是通过调用setter方法来实现注入的

    1. public class Person {
    2. private String name;
    3. private int age;
    4. public String getName() {
    5. return name;
    6. }
    7. public void setName(String name) {
    8. System.out.println("Spring调用setName");
    9. this.name = name;
    10. }
    11. public int getAge() {
    12. return age;
    13. }
    14. public void setAge(int age) {
    15. System.out.println("Spring调用setName");
    16. this.age = age;
    17. }
    18. @Override
    19. public String toString() {
    20. return "Person{" +
    21. "name='" + name + '\'' +
    22. ", age=" + age +
    23. '}';
    24. }
    25. }

    2)接下来执行测试代码,此处是直接使用了Spring的配置文件注入(在这里有疑问的同学,可以移步我前面的文章)

    1. public void test3() {
    2. // 通过Spring提供的接口获取到类对象
    3. ApplicationContext ctx =
    4. new ClassPathXmlApplicationContext("applicationContext.xml");
    5. Person person = (Person) ctx.getBean("person");
    6. // 传统的方式是直接用person对象调用setter方法,但是会产生耦合
    7. // person.setName("李四");
    8. // person.setAge(20);
    9. System.out.println(person);
    10. }

    此时运行的结果进行了打印,说明Spring底层进行注入是通过调用类中的setter方法,这也就说为什么一定要在类中加上setter方法才能进行注入的原因。这种注入方式也叫做setter注入

     

    二、setter注入详解

    setter注入是Spring通过配置文件调用类中的setter方法来实现的。此时是使用property+value标签来实现注入的,其中property对应的是需要注入的属性,value对应的是给属性注入的值。好!到这里问题就出来了,这里String和int类型是这样注入的,那换成其他类型(double、char、数组)怎么去注入呢?

    接下来通过一张图来展示setter注入的两种方式,一种是JDK内置类型注入方式、另一种是用户自定义类型的注入方式。其中JDK内置类型也就是Java自带的类型包括八种基本类型(int...)、数组...,自定义类型则是用户自己定义的(比如userDAO....)

     

    三、JDK内置类型注入方式

    之前我们已经知道了8中基本类型的注入方式了,那么接下来就演示一下上图中的其他几种类型的注入方式

    3.1 数组类型

    首先不管是什么类型的注入,都需要添加setter方法,不然注入是会失败的。在Person类中添加一个emails数组,这里为了简洁其他的属性就不展示了

    1. public class Person {
    2. // 为了后续测试方便这里就直接用public了
    3. public String[] emails;
    4. public String[] getEmails() {
    5. return emails;
    6. }
    7. public void setEmails(String[] emails) {
    8. this.emails = emails;
    9. }
    10. }

    其实数组的注入就是添加一个list标签,然后在list标签中使用value标签注入值

    1. <bean id="person" class="com.gl.demo.model.Person">
    2. <property name="emails">
    3. <list>
    4. <value>12456@qq.comvalue>
    5. <value>78910@qq.comvalue>
    6. list>
    7. property>
    8. bean>

    接下来测试emails中是否真的注入了值 

    1. public void test3() {
    2. ApplicationContext ctx =
    3. new ClassPathXmlApplicationContext("applicationContext.xml");
    4. Person person = (Person) ctx.getBean("person");
    5. for (String s:person.emails) {
    6. System.out.println(s);
    7. }
    8. }

    结果显示注入已经成功了

    3.2 set集合类型

    添加一个号码集合,同样的还是需要在类中添加setter方法

    1. public class Person {
    2. public Set tels;
    3. public Set getTels() {
    4. return tels;
    5. }
    6. public void setTels(Set tels) {
    7. this.tels = tels;
    8. }
    9. }

    为set属性注入的时候就是添加一个set标签,然后在set标签中添加value标签注入值 

    1. <bean id="person" class="com.gl.demo.model.Person">
    2. <property name="tels">
    3. <set>
    4. <value>1381111111value>
    5. <value>1521111111value>
    6. <value>1981111111value>
    7. <list>list>
    8. set>
    9. property>
    10. bean>
    1. public void test() {
    2. ApplicationContext ctx =
    3. new ClassPathXmlApplicationContext("applicationContext.xml");
    4. Person person = (Person) ctx.getBean("person");
    5. for (String s:person.tels) {
    6. System.out.println(s);
    7. }
    8. }

    3.3 list集合

    list集合的注入方式其实是和数组的注入方式是一致的,因为list集合的底层就是通过数组来实现的,这里参考2.1.1即可。但是值得注意的是,list集合注入的时候也可以在list标签中写其他的标签

    3.4 map集合

    为了文章的简洁性这里就不再写setter方法了,接下来添加一个qq的map属性

    public Map qqs;
    
    1. <bean id="person" class="com.gl.demo.model.Person">
    2. <property name="qqs">
    3. <map>
    4. <entry>
    5. <key>
    6. <value>pengyuyanvalue>
    7. key>
    8. <value>
    9. 2656111111
    10. value>
    11. entry>
    12. <entry>
    13. <key>
    14. <value>wuyanzuvalue>
    15. key>
    16. <value>
    17. 3332262654
    18. value>
    19. entry>
    20. map>
    21. property>
    22. bean>

    3.5 properties类型

    public Properties props;
    
    1. <bean id="person" class="com.gl.demo.model.Person">
    2. <property name="props">
    3. <props>
    4. <prop key="url">mysqlprop>
    5. <prop key="name">rootprop>
    6. <prop key="password">123prop>
    7. props>
    8. property>
    9. bean>

    四、用户自定义类型

    此时我有两个类,一个是UserService类,另一个是UserDao类,其中UserService中有一个UserDao的对象,此时要怎么为userDao对象赋值呢?一定不要忘记了属性的setter方法!

    1. public class UserService {
    2. // 此时使用setter注入的方式为userDao赋值
    3. UserDao userDao;
    4. // 为了演示方便业务逻辑就不写了
    5. public UserDao getUserDao() {
    6. return userDao;
    7. }
    8. public void setUserDao(UserDao userDao) {
    9. this.userDao = userDao;
    10. }
    11. }
    1. public class UserDao {
    2. // 此处为了展示简洁就不写具体的逻辑了
    3. }

    首先进行分析,我要在UserService类中为UserDao的类对象赋值,是不是应该要先创建UserService类呢?创建好了之后,由于UserDao是一个类对象,那不是不是可以使用Bean标签直接来创建呢?通过这里的分析我们得到了如下配置文件书写的方式

    1. <bean id="userService" class="com.gl.demo.service.UserService" >
    2. <property name="userDao">
    3. <bean id="userDao" class="com.gl.demo.dao.UserDao"/>
    4. property>
    5. bean>

    写到这里,问题出来了,我的service在以后是不是有很多啊,那我每次创建一个service类是不是每次都要创建一个userDao对象,这样是不是就造成了严重的代码冗余?其次创建的userDao对象多了是不是就会浪费Jvm中的资源。为了解决这个问题,接下来采取以下方法:

    1)首先先使用Bean创建好需要的类对象

    2)然后使用 一个 ref 引用标签来引用创建好的 对象标签的id即可

    1. <bean id="userDao" class="com.gl.demo.dao.UserDao"/>
    2. <bean id="userService" class="com.gl.demo.service.UserService">
    3. <property name="userDao">
    4. <ref bean="userDao"/>
    5. property>
    6. bean>

    简化版: 

    1. <bean id="userDao" class="com.gl.demo.dao.UserDao"/>
    2. <bean id="userService" class="com.gl.demo.service.UserService" p:userDao-ref="userDao"/>

    至此,Spring中setter注入的几种常见的方式就完毕了。以上列举的只是使用的比较多的类型,并不是说只有这些类型。

  • 相关阅读:
    Python二分查找
    如何规避需求分析缺陷,提高需求分析质量?
    【SpringMVC]获取参数的六种方式
    J2EE从入门到入土02.List集合解析
    关于《web课程设计》网页设计 用html css做一个漂亮的网站 仿新浪微博个人主页
    【广州华锐互动】智轨列车AR互动教学系统
    Linux服务器搭建Docker
    Quanto: PyTorch 量化工具包
    STM32CubeMX配置生成FreeRTOS项目
    自动驾驶——构建仿真系统
  • 原文地址:https://blog.csdn.net/x2656271356/article/details/133892619