• 【Spring】依赖注入方式(附代码理解使用)——setter与构造器注入;依赖自动装配;使用p命名空间注入属性值;注入数组集合类型



    【向一个类中传递数据的方式?①普通方法、②构造方法】
    【依赖注入描述了容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串?①引用类型、②简单类型(基本数据类型与String)】

    普通方法(setter注入):

    使用setter注入、标签、ref属性

    setter注入——1.引用类型
    • 在bean中定义引用类型属性并提供可访问的set方法(第一期spring举例过,此处实例省略dao层和接口)

      public class UserServiceImpl implements UserDao {
      	@Setter
      	private UserDao userDao;		
      	//一个方法
      	public int addNewUser(User user) {
          	return userDao.addNewUser(user);
      	}
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 在配置文件中使用property标签注入ref属性引用类型对象

      <bean id="userDao" class="com.jules.dao.impl.UserDaoImpl">bean>
      
      <bean id="userService" class="com.jules.service.impl.UserServiceImpl">
          <property name="userDao" ref="userDao"/>
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5

      【如果不止一个引用类型,多个private UserDao userDao;,只需要在配置处配置bean,并添加标签注入使用即可】

    setter注入——2.简单类型(基本数据类型与String)

    使用setter注入、标签、value属性注入值

    • 一个HelloWorld类中写一个String类型对象,提供可访问的set方法

      public class HelloWorld {
          @Setter
          private String message;
      
          public void show(){
              System.out.println("打印的信息"+message);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 配置:使用property标签、value属性注入值

      
      <bean id="helloWorld" class="com.hz.test.HelloWorld">
          <property name="message" value="辣椒面撒多了的烤串"/>
      bean>
      
      • 1
      • 2
      • 3
      • 4
    • 测试

      public class main01 {
          public static void main(String[] args) {
              //使用ClassPathXmlApplicationContext读取配置文件
              ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
              //使用getBean("bean中ID属性值")获取对象
              HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");
              helloWorld.show();
          }
      }
      
      //控制台打印:辣椒面撒多了的烤串
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    构造方法(构造器注入):

    使用构造器注入、标签、ref属性

    示例准备:

    //dao接口
    public interface UserDao {
        public int addNewUser(User user);
    }
    
    //dao实现
    public class UserDaoImpl implements UserDao {
        public int addNewUser(User user) {
            System.out.println("新添加一个对象~~~");
            return 0;
        }
    }
    
    //service接口:
    public interface UserService {
        public int addNewUser(User user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    构造器注入——引用类型
    • 在bean中定义引用类型属性并提供可访问的构造方法

      //service实现
      //@AllArgsConstructor   //有参构造函数
      @NoArgsConstructor    //无参构造函数
      public class UserServiceImpl implements UserService {
          private UserDao userDao;
          
      	//有参构造,上面注解的形式或者↓
          public UserServiceImpl(UserDao userDao1111) {
              this.userDao = userDao;
          }
      
          public int addNewUser(User user) {
              return userDao.addNewUser(user);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    • 配置中使用constructor-arg标签ref属性

      <bean id="userDao" class="com.jules.dao.impl.UserDaoImpl">bean>
      <bean id="userService" class="com.jules.service.impl.UserServiceImpl">
       
          //注意代码:这样写name中的值与构造方法的形参"userDao1111"对应,名称耦合
          //<constructor-arg name="userDao1111" ref="userDao" />
         
          <constructor-arg>
              <ref bean="userDao">ref>
          constructor-arg>
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    构造器注入——普通类型
    • 一个String类型、一个int类型,并提供可访问的构造方法

      public class HelloWorld {
          private String message;
          private int num;
      
      	public HelloWorld (String message, int num) {
      		this.message = message;
      		this.num = num;
      	}
      
          public void show(){
              System.out.println("打印的信息"+message+"----"+num+"条");
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • 配置:使用constructor-arg标签、value属性注入值

      
      <bean id="helloWorld" class="com.hz.test.HelloWorld">
      	
          <constructor-arg name="message" value="辣椒面撒多了的烤串"/>
          <constructor-arg name="num" value="10"/>      
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      
      <bean id="helloWorld" class="com.hz.test.HelloWorld">
          
          <constructor-arg type="java.lang.Sring" value="辣椒面撒多了的烤串"/>
          <constructor-arg type="int" value="10"/> 
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      
      <bean id="helloWorld" class="com.hz.test.HelloWorld">
          
          <constructor-arg index="0" value="辣椒面撒多了的烤串"/>
          <constructor-arg index="1" value="10"/>        
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    【===========================三种形式有利有弊选择使用========================】

    依赖注入方式选择

    • 1.强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
    • 2.可选依赖使用setter注入进行,灵活性强
      1. Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
    • 4.如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
    • 5.实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
    • 6.自己开发的模块推荐使用setter注入

    依赖自动装配

    • 概念:IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
    • 自动装配方式:
      • 按类型:byType,(常用)类型匹配必须唯一
      • 按名称:byName(不推荐)
      • 按构造方法:constructor
      • 不启用自动装配:no
    按类型:
    //service实现
    	public class UserServiceImpl implements UserDao {
    			private UserDao userDao;	
    			//ser方法必须有	
    			public voidsetUserDao(UserDao userDao) {
    				this,userDao = userDao
    			}
    			//一个方法
    			public void save() {
    				System.out.println("user service save……");
    	        	userDao.save();
    	   		}
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    <bean id="userDao" class="com.jules.dao.impl.UserDaoImpl">bean>
    																    //按类型自动装配
    <bean id="userService" class="com.jules.service.impl.UserServiceImpl" autowire="byType"/>
    
    • 1
    • 2
    • 3

    注意:

    • 按类型装配,没有对应的注入,报错:
      在这里插入图片描述
    • 多个bean的注入:com.jules.dao.impl.UserDaoImpl对应的bean不唯一在这里插入图片描述
    按名称:
    //service实现
    	public class UserServiceImpl implements UserDao {
    			private UserDao userDao;	
    			//ser方法必须有	
    			public void setUserDao(UserDao userDao) {
    				this,userDao = userDao
    			}
    			//一个方法
    			public void save() {
    				System.out.println("user service save……");
    	        	userDao.save();
    	   		}
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    //此时id与private UserDao userDao相对应
    <bean id="userDao" class="com.jules.dao.impl.UserDaoImpl">bean>
    <bean id="userDao2" class="com.jules.dao.impl.UserDaoImpl">bean>  
    																     //按名称自动装配
    <bean id="userService" class="com.jules.service.impl.UserServiceImpl" autowire="byName"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    【注意:倘若同一个引用使用不同的bean,只会匹配拥有的bean;一般都只会对应一个实现类,< bean >中的id可以省略】

    依赖自动装配特征

    • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
    • 使用按类型装配时( byType )必须保障容器中相同类型的bean唯一,推荐使用
    • 使用按名称装配时( byName )必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
    • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

    使用p命名空间注入属性值

    • p命名空间的特点:使用属性而不是子元素的形式配置Bean的属性,从而简化了配置代码
      对于直接量(基本数据类型、字符串)属性:p:属性名=“属性值”
      对于引用Bean的属性:p:属性名-ref="Bean的id"
      
      • 1
      • 2
    • 使用前要现在Spring配置中引入p命名空间
      xmlns:p="http://www.springframework.org/schema/p"
      
      • 1
    • 使用p命名空间注入属性值
      
      <bean id="zhangGaSay" class="service.Person" p:who="张嘎"
      	p:say="三天不打小鬼子,手都痒痒!" />
      <bean id="RodSay" class="service.Person" p:who="Rod"
      	p:say="世界上有10种人,认识二进制的和不认识二进制的。" />
      
      
      <bean id="userDao" class="dao.impl.UserDaoImpl" />
      
      <bean id="userService" class="service.impl.UserServiceImpl"
          p:dao-ref="userDao"/>  
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 完整范例:
    //dao接口
    public interface UserDao {
        public int addNewUser(User user);
    }
    //daos实现
    public class UserDaoImpl implements UserDao {
    
        public int addNewUser(User user) {
            System.out.println("新添加一个对象~~~"+user.getUserName());
            return 0;
        }
    }
    //service接口
    public interface UserService {
        public int addNewUser(User user);
    }
    //service实现
    public class UserServiceImpl implements UserService {
    	//set方法
        @Setter
        private UserDao userDao;
        @Setter
        private String uname;
        @Setter
        private String ucode;
    
        public int addNewUser(User user) {
            user.setUserName(uname);
            user.setUserCode(ucode);
    
            return userDao.addNewUser(user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    
    
    <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.xsd">
    
        <bean id="userDao" class="com.jules.dao.impl.UserDaoImpl">bean>
        <bean id="userService" class="com.jules.service.impl.UserServiceImpl"
                    p:uname="张三"
                    p:ucode="1001"
                    p:userDao-ref="userDao">
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    public class UserServiceImplTest {
        @Test
        public void addNewUser() {
                //使用ClassPathXmlApplicationContext读取配置文件
                ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
                //使用getBean("bean中ID属性值")获取对象
                UserService userService = (UserService) context.getBean("userService");
                userService.addNewUser(new User());
        }
    }
    
    //控制台输出:新添加一个对象~~~张三
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注入不同数据类型(集合、数组、set、Map、Properties类型)

    直接放代码

    @Setter
    public class EntityTest {
    	private List<String> list; // List类型
    	private String[] array; // 数组类型
    	private Set<String> set; // Set类型
    	private Map<String, String> map; // Map类型
    	private Properties props; // Properties类型
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    
        <bean id="entityTest" class="com.jules.entity.EntityTest">
            
            <property name="list">
                <list>
                    <value>注入value>
                    <value>Listvalue>
                    <value>类型value>
                list>
            property>
            
            <property name="array">
                <list>
                    <value>注入value>
                    <value>Array数组value>
                    <value>类型value>
                list>
            property>
            
            <property name="set">
                <set>
                    <value>Julesvalue>
                    <value>朱尔斯value>
                set>
            property>
            
            <property name="map">
                <map>
                    <entry>
                        <key><value>5555value>key>
                        <value>朱尔斯value>
                    entry>
                    <entry>
                        <key><value>6666value>key>
                        <value>Julesvalue>
                    entry>
                map>
            property>
           
            
            <property name="props">
                <props>
                    <prop key="url">lochost:xxxx/xx/x/xprop>
                    <prop key="driver">aaaaaprop>
                    <prop key="username">rootprop>
                    <prop key="password">rootprop>
                props>
            property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    细到不能再细的 Spring Cloud Gateway 原理分析(内含多张图片讲解)
    vue 语法--表单取值,组件通信
    【状态估计】将变压器和LSTM与卡尔曼滤波器结合到EM算法中进行状态估计(Python代码实现)
    图数据技术护航网络安全 - Neo4j 大中华区总经理 方俊强
    命令模式(command)
    Linux系统批量释放deleted文件占用的空间
    XLA之HloModule“合并”
    qt自定义控件之TextEdit
    设计模式之桥接模式(六)
    OpenAI“政变”进行时,“百模大战”接下来该战什么?
  • 原文地址:https://blog.csdn.net/m0_70083523/article/details/127601032