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


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

普通方法(setter注入):

使用setter注入、<property>标签、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);
    	}
    }
    
  • 在配置文件中使用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>
    

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

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

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

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

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

    <!--实例化HelloWorld类型-->
    <bean id="helloWorld" class="com.hz.test.HelloWorld">
        <property name="message" value="辣椒面撒多了的烤串"/>
    </bean>
    
  • 测试

    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();
        }
    }
    
    //控制台打印:辣椒面撒多了的烤串
    

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

使用构造器注入、<constructor-arg>标签、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);
}
构造器注入——引用类型
  • 在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);
        }
    }
    
  • 配置中使用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>
    
构造器注入——普通类型
  • 一个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+"条");
        }
    }
    
  • 配置:使用constructor-arg标签、value属性注入值

    <!--实例化HelloWorld类型-->
    <bean id="helloWorld" class="com.hz.test.HelloWorld">
    	<!--形式1:name的值与形参名称一致-->
        <constructor-arg name="message" value="辣椒面撒多了的烤串"/>
        <constructor-arg name="num" value="10"/>      
    </bean>
    
    <!--实例化HelloWorld类型-->
    <bean id="helloWorld" class="com.hz.test.HelloWorld">
        <!--形式2:type解决形参名称耦合-->
        <constructor-arg type="java.lang.Sring" value="辣椒面撒多了的烤串"/>
        <constructor-arg type="int" value="10"/> 
    </bean>
    
    <!--实例化HelloWorld类型-->
    <bean id="helloWorld" class="com.hz.test.HelloWorld">
        <!--形式3:index解决参数类型重复类型-->
        <constructor-arg index="0" value="辣椒面撒多了的烤串"/>
        <constructor-arg index="1" value="10"/>        
    </bean>
    

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

依赖注入方式选择

  • 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();
	   		}
		}
<bean id="userDao" class="com.jules.dao.impl.UserDaoImpl"></bean>
																    //按类型自动装配
<bean id="userService" class="com.jules.service.impl.UserServiceImpl" autowire="byType"/>

注意:

  • 按类型装配,没有对应的注入,报错:
    在这里插入图片描述
  • 多个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();
	   		}
		}
//此时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"/>

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

依赖自动装配特征

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

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

  • p命名空间的特点:使用属性而不是子元素的形式配置Bean的属性,从而简化了配置代码
    对于直接量(基本数据类型、字符串)属性:p:属性名=“属性值”
    对于引用Bean的属性:p:属性名-ref="Bean的id"
    
  • 使用前要现在Spring配置中引入p命名空间
    xmlns:p="http://www.springframework.org/schema/p"
    
  • 使用p命名空间注入属性值
    <!-- p命名空间注入-->
    <bean id="zhangGaSay" class="service.Person" p:who="张嘎"
    	p:say="三天不打小鬼子,手都痒痒!" />
    <bean id="RodSay" class="service.Person" p:who="Rod"
    	p:say="世界上有10种人,认识二进制的和不认识二进制的。" />
    
    <!--定义UserDao对象,并指定id为userDao-->
    <bean id="userDao" class="dao.impl.UserDaoImpl" />
    <!--定义UserService对象,并指定id为userService-->
    <bean id="userService" class="service.impl.UserServiceImpl"
        p:dao-ref="userDao"/>  
    
  • 完整范例:
//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);
    }
}
<!-- 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"
       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>
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());
    }
}

//控制台输出:新添加一个对象~~~张三

注入不同数据类型(集合、数组、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类型
}
<!--注入:此处所有的name都是TestEntity中的属性-->
    <bean id="entityTest" class="com.jules.entity.EntityTest">
        <!--注入List类型-->
        <property name="list">
            <list>
                <value>注入</value>
                <value>List</value>
                <value>类型</value>
            </list>
        </property>
        <!--注入数组类型-->
        <property name="array">
            <list>
                <value>注入</value>
                <value>Array数组</value>
                <value>类型</value>
            </list>
        </property>
        <!--set注入-->
        <property name="set">
            <set>
                <value>Jules</value>
                <value>朱尔斯</value>
            </set>
        </property>
        <!--map注入-->
        <property name="map">
            <map>
                <entry>
                    <key><value>5555</value></key>
                    <value>朱尔斯</value>
                </entry>
                <entry>
                    <key><value>6666</value></key>
                    <value>Jules</value>
                </entry>
            </map>
        </property>
       <!-- 另一种形式
       <property name="map">
            <map>
                <entry key="jules" value="22">
                <entry key="xxxx" value="22">
                <entry key="yyyy" value="22">
            </map>   
        </property>
         -->
        <!--Properties类型注入-->
        <property name="props">
            <props>
                <prop key="url">lochost:xxxx/xx/x/x</prop>
                <prop key="driver">aaaaa</prop>
                <prop key="username">root</prop>
                <prop key="password">root</prop>
            </props>
        </property>
    </bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

朱尔斯Jules

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值