目录
Spring的属性注入
/    

Spring的属性注入

基于xml文件的属性注入

构造方法注入

  • 具体参照setter注入
<!--    使用构造方法注入方式装配ConplexUser实例user1-->
    <bean id="user1" class="com.model.ComplexUser">
        <constructor-arg index="0" value="张三"/>
        <constructor-arg index="1">  <!--构造方法中参数的位置-->
            <list>
                <value>唱歌</value>
                <value>跳舞</value>
                <value>爬山</value>
            </list>
        </constructor-arg>
        <constructor-arg index="2">
            <map>
                <entry key="dalian" value="大连"/>
                <entry key="beijing" value="北京"/>
                <entry key="shanghai" value="上海"/>
            </map>
        </constructor-arg>
        <constructor-arg index="3">
            <set>
                <value>陈恒 100</value>
                <value>陈恒 101</value>
                <value>陈恒 102</value>
            </set>
        </constructor-arg>
        <constructor-arg>
            <array>
                <value>aaa</value>
                <value>bbb</value>
            </array>
        </constructor-arg>
    </bean>
<!--    使用属性的setter方法注入方式装配  complexUser实例2-->
    <bean id="user2" class="com.model.ComplexUser">
        <property name="uname" value="李四"/>
        <property name="hobbyList">
            <list>
                <value>看书</value>
                <value>学习spring</value>
            </list>
        </property>
        <property name="residenceMap">
            <map>
                <entry key="dalian" value="大连"/>
                <entry key="beijing" value="北京"/>
                <entry key="shanghai" value="上海"/>
            </map>
        </property>
        <property name="aliasSet">
            <set>
                <value>陈恒 100</value>
                <value>陈恒 101</value>
                <value>陈恒 102</value>
            </set>
        </property>
        <property name="array">
            <array>
                <value>aaa</value>
                <value>bbb</value>
            </array>
        </property>
    </bean>

setter方法注入

  • Student.java

    package cn.lacknb.bean;
    
    public class Student {
    
        private String name;
        private String sex;
    
        public Student() {
        }
    
        public Student(String name, String sex) {
            this.name = name;
            this.sex = sex;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", sex='" + sex + '\'' +
                    '}';
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    }
    
    
  • User.java

    package cn.lacknb.bean;
    
    public class User {
    
        private String name;
        private int age;
        private String sex;
        private Student student;
    
        public Student getStudent() {
            return student;
        }
    
        public void setStudent(Student student) {
            this.student = student;
        }
    
        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;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public User() {
    
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", sex='" + sex + '\'' +
                    ", student=" + student +
                    '}';
        }
    }
    
    
  • applicationContext.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
    https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="student" class="cn.lacknb.bean.Student">
            <property name="name" value="张三"/>
            <property name="sex" value="男"/>
        </bean>
    
        <bean id="user" class="cn.lacknb.bean.User">
            <property name="name" value="李老师"/>
            <property name="sex" value="女"/>
            <property name="age" value="12"/>
            <property name="student" ref="student"/>
        </bean>
    </beans>
    
  • 测试类 MyTest.java

    package cn.lacknb.test;
    
    import cn.lacknb.bean.Animals;
    import cn.lacknb.bean.User;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
    
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            User user = (User) context.getBean("user");
            System.out.println(user);
        }
    }
    
    

域属性自动注入 autowire

  • byName

    • xml中的bean的id需要和实体类的属性名保持一致
  • byType

    • 会根据类型查找, 如果出现两个相同类型会报错
    • 如果出现需要查找实体类的子类, 也会报异常。
  • 例子:

    • 需要上面例子的两个实体类

    • Animals.java

      package cn.lacknb.bean;
      
      import java.lang.reflect.Array;
      import java.util.*;
      
      public class Animals {
      
          private String name;
          private String[] colors;
          private List<String> hobbyList;
          private Map<String, String> hobbyMap;
          private Set<String> hobbySet;
          private Properties hobbyProps;
          private User user;
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public User getUser() {
              return user;
          }
      
          public void setUser(User user) {
              this.user = user;
          }
      
          public String[] getColors() {
              return colors;
          }
      
          public void setColors(String[] colors) {
              this.colors = colors;
          }
      
          public List<String> getHobbyList() {
              return hobbyList;
          }
      
          public void setHobbyList(List<String> hobbyList) {
              this.hobbyList = hobbyList;
          }
      
          public Map<String, String> getHobbyMap() {
              return hobbyMap;
          }
      
          public void setHobbyMap(Map<String, String> hobbyMap) {
              this.hobbyMap = hobbyMap;
          }
      
          public Set<String> getHobbySet() {
              return hobbySet;
          }
      
          public void setHobbySet(Set<String> hobbySet) {
              this.hobbySet = hobbySet;
          }
      
          public Properties getHobbyProps() {
              return hobbyProps;
          }
      
          public void setHobbyProps(Properties hobbyProps) {
              this.hobbyProps = hobbyProps;
          }
      
          @Override
          public String toString() {
              return "Animals{" +
                      "name='" + name + '\'' +
                      ", colors=" + Arrays.toString(colors) +
                      ", hobbyList=" + hobbyList +
                      ", hobbyMap=" + hobbyMap +
                      ", hobbySet=" + hobbySet +
                      ", hobbyProps=" + hobbyProps +
                      ", user=" + user +
                      '}';
          }
      }
      
      
    • 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
      https://www.springframework.org/schema/beans/spring-beans.xsd">
      
          <bean id="student" class="cn.lacknb.bean.Student">
              <property name="name" value="张三"/>
              <property name="sex" value="男"/>
          </bean>
      
          <bean id="user" class="cn.lacknb.bean.User" autowire="byType">
              <property name="name" value="李老师"/>
              <property name="sex" value="女"/>
              <property name="age" value="12"/>
              <!--<property name="student" ref="student"/>-->
          </bean>
      
      
          <!--       分界线        -->
      
          <bean id="animals" class="cn.lacknb.bean.Animals" autowire="byName">
              <property name="name" value="哈士奇"/>
              <property name="colors">
                  <array>
                      <value>红色</value>
                      <value>白色</value>
                      <value>蓝色</value>
                  </array>
              </property>
              <property name="hobbyList">
                  <list>
                      <value>吃骨头</value>
                      <value>发出叫声</value>
                      <value>吃狗食</value>
                  </list>
              </property>
              <property name="hobbyMap">
                  <map>
                      <entry key="1" value="吃骨头"/>
                      <entry key="2" value="发出叫声"/>
                      <entry key="3" value="吃狗食"/>
                  </map>
              </property>
              <property name="hobbyProps">
                  <props>
                      <prop key="1">吃骨头</prop>
                      <prop key="2">发出叫声</prop>
                      <prop key="3">吃狗食</prop>
                  </props>
              </property>
              <property name="hobbySet">
                  <set>
                      <value>吃骨头</value>
                      <value>发出叫声</value>
                      <value>吃狗食</value>
                  </set>
              </property>
          </bean>
      </beans>
      

      UTOOLS1571888929812.png

SPEL注入

  • 随机数

    <property name="age" value="#{T(java.lang.Math).random()*100}" />

    • 例如将上面的user中的age为随机数

      KN6RZ8.png

      KNcVFe.png

  • 获取实体类中的值 和 调用实体类中的方法

    #{对象.属性}

    #{对象.方法}

  • 三目运算

    #{user.age>30?30:user.age}

    如果输入的值大于30, 就取30, 否则就取输入的值。

基于注解的方式注入

在实体类中使用

  • @Component("组件的名字")

    • @Value("属性值")
    • @Autowired("byName或者byType") --- 对象自动装配
  • xml文件配置

    <context:component-scan base-package="cn.lacknb"/>  扫描指定包下的所有的类
    

@Component

该注解是一个泛化的概念, 仅仅表示一个组件对象 ( Bean ), 可以通过作用在如何层次上

@Repository

该注解用于将数据访问层 ( DAO ) 的类标识为Bean, 即注解数据访问层Bean, 其功能与@Component相同

@Service

该注解用于标注一个业务逻辑组件类 ( Service层 ), 其功能与@Component相同

@Controller

该注解用于标注一个控制器组件类 ( Spring MVC 的Controller ), 其功能与@Component相同

@Autowired

  • 使用@Autowired时, 首先在容器查找对应类型的bean
    • 当查询结果刚好为一个时, 就将该bean装配给指定的数据
    • 当查询结果不止一个时, @Autowired会根据名称来查找, 如果还是没有找到, 就会抛出异常.
    • 当查询结果为空时, 会抛出异常, 可以使用@Autowired( required = false )解决.

@Resource

​ 该注解与@Autowired的功能一样, 区别在于该注解默认是按照名称来装配注入的, 只有当找不到

与名称匹配的Bean时才会按照类型来装配注入; 而@Autowired默认是按照Bean类型进行装配的, 如果

想按照名称装配注入, 则需要和@Qualitier注解一起使用

​ @Resource注解有两个属性--name和type. name属性指定Bean实例名称, 即按照名称来装配注入;

type属性指定Bean类型, 即按照Bean的类型进行装配

@Qualifier

​ 该注解与@Autowired注解配合使用, 当@Autowired注解需要按照名称来装配注入时需要和该注解

一起使用, Bean的实例名称由@Qualitier注解的参数指定.

在上面几个注解中, 虽然@Repository、@Service和@Controller等注解的功能与@Component注解相同, 但为了使类的标注更加气你(层次化), 在实际开发中推荐使用@Repository标注数据访问层(DAO层)、使用@Service标注业务逻辑层(Service层)、使用@Controller标注控制器层(控制层)

例子

  • 创建DAO层 --- TestDao.java

    package cn.lacknb.dao;
    
    public interface TestDao {
    
        public void save();
    
    }
    
    
  • 创建TestDaoImpl.java

    package cn.lacknb.dao;
    
    import org.springframework.stereotype.Repository;
    
    @Repository("testDao")
    /*
    * 相当于@Repository, 但如果在service层中使用@Resource(name = "testDao"), testDao不能省略
    * */
    public class TestDaoImpl implements TestDao {
        @Override
        public void save() {
            System.out.println("testDao save");
        }
    }
    
    
  • 创建Service层 --- TestService.java

    package cn.lacknb.service;
    
    public interface TestService {
    
        public void save();
    
    }
    
    
  • TestServiceImpl.java

    package cn.lacknb.service;
    
    import cn.lacknb.dao.TestDao;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    @Service("testService")  // 相当于@Service
    public class TestServiceImpl implements TestService {
    
        @Resource(name = "testDao")  // 注意这里@Resource中参数不止一个, 所以不能直接写testDao
        // 相当于@Autowired, 只不过@Autowired默认按照Bean类型装配, Resource默认是按名称装配
        private TestDao testDao;
    
        @Override
        public void save() {
            testDao.save();
            System.out.println("testService save");
        }
    }
    
    
  • 创建Controller层 --- TestController.java

    当一个组件在某个扫描过程中被自动检测到时,会根据那个扫描器的BeanNameGenerator 策略生成它的bean名称。默认情况下,任何包含 name值的Spring“典型”注解 (@Component、@Repository、 @Service和@Controller) 会把那个名字 提供给相关的bean定义。如果这个注解不包含name值或是其他检测到的组件 (比如被自定义过滤器发现的),默认bean名称生成器会返回小写开头的非限定(non-qualified)类名。

    package cn.lacknb.Controller;
    
    import cn.lacknb.service.TestService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    @Controller  // 这里可以自定义名称, 默认为这个类的名称, 小写开头 testController
    public class TestController {
    
        @Autowired
        private TestService testService;
    
        public void  save(){
            testService.save();
            System.out.println("testController save");
        }
    }
    
    
  • 配置注解

    <?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    
    <!--    扫描指定包下的组件-->
        <context:component-scan base-package="cn.lacknb"/>
    
    </beans>
    
  • 创建测试类 TestMoreAnnotation.java

    package cn.lacknb.test;
    
    import cn.lacknb.Controller.TestController;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class TestMoreAnnotation {
    
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            TestController controller = (TestController) context.getBean("testController");  // 默认是该类的类名testController, 也可以在注解中自定义
            controller.save();
        }
    
    }
    
    
  • 运行结果

    KUfE1e.png


标题:Spring的属性注入
作者:gitsilence
地址:https://blog.lacknb.cn/articles/2019/10/25/1577974163166.html