Spring学习之依赖注入(DI)

1、准备一个类Car

public class Car {
	
	private String brand;   // 品牌
	
	private String crop;    // 厂商
	
	private Double price;   // 价格

	public Car() {}
	
	public Car(String brand, String crop, Double price) {
		this.brand = brand;
		this.crop = crop;
		this.price = price;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getCrop() {
		return crop;
	}

	public void setCrop(String crop) {
		this.crop = crop;
	}

	public Double getPrice() {
		return price;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Car [brand=" + brand + ", crop=" + crop + ", price=" + price + "]";
	}
}

2.1、在配置文件spring-di.xml中配置Car,实现第一种注入方式:setter注入,类必须要有Set方法

<?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">
	<!-- DI依赖注入的方式:set方法注入 -->
	<bean id="car" class="com.spring.entity.Car">
		<property name="brand" value="帝豪"></property>
		<property name="crop" value="吉利"></property>
		<property name="price" value="70000.0"></property>
	</bean>
</beans>

2.2、执行测试:

package com.test.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring.entity.Car;

public class CarTest {
	
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-di.xml");
		Car car = ctx.getBean("car", Car.class);
		System.out.println(car.toString());
	}	
}

2.3、测试结果:

Car [brand=帝豪, crop=吉利, price=70000.0]

3.1、配置spring-di.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">
	<!-- DI依赖注入的方式:构造器注入 -->
	<bean id="car1" class="com.spring.entity.Car">
		<constructor-arg value="奥迪"/>
		<constructor-arg value="一汽"/>
		<constructor-arg value="400000.0"/>
	</bean>
</beans>

3.2、执行测试:

package com.test.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring.entity.Car;

public class CarTest {
	
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-di.xml");
		
		Car car1 = ctx.getBean("car1", Car.class);
		System.out.println(car1.toString());

	}
}

3.3、测试结果:

Car [brand=奥迪, crop=一汽, price=400000.0]

3.4、将配置文件中的构造参数顺序颠倒后

<?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">
	<!-- DI依赖注入的方式:构造器注入 -->
	<bean id="car1" class="com.spring.entity.Car">
		<constructor-arg value="奥迪"/>
        <constructor-arg value="400000.0"/>
		<constructor-arg value="一汽"/>
	</bean>
</beans>

3.5、执行结果:解析不到匹配的构造方法

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'car1' defined in class path resource [spring-di.xml]: Could not resolve matching constructor

3.6、解决办法:在<constructor-arg>中加入index,指定参数的顺序即可

<?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">
	<!-- DI依赖注入的方式:构造器注入 -->
	<bean id="car1" class="com.spring.entity.Car">
		<constructor-arg value="奥迪"  index="0"/>
        <constructor-arg value="400000.0" index="2"/>
		<constructor-arg value="一汽" index="1"/>
	</bean>
</beans>

4.1、实现注入的第三种方式:使用注解注入 @Autowired或者@Resource

4.1.1、使用@Resource注解

@Resource注解 是java自带的注解,spring内部也支持这个注解的自动注入,它默认是使用byName方式注入,找不到name再找type,两者都找不到就会抛异常。

@Resource注解 可以加在字段、set方法、构造方法上,使用方式和@Autowired类似,只是它没有required属性

4.1.2、使用@Autowired注解

@Autowired注解默认使用byType方式注入,没找到的话,会使用byName方式再次尝试,两种方式都找不到,就会抛出异常。如果不希望看到抛异常,通过设置required=false,spring如果没找到对应的bean就不注入,也不会抛异常。

实际生产中,@Autowired注解通常会与@Qualifier注解同时使用。当接口有多个实现类时,byType方式就无法注入bean了,需要@Qualifier("userService") 指定name,才可以正确注入

至于为什么不用@Resource,我觉得这个看个人习惯,至于有没有其他原因,目前还不知道,如果有,以后再补充

看网上还有其他两种,一个是静态工厂方法、一个是实力工厂方法,基于目前项目不怎么用这两种方式,所以,暂时不写了,讲一下大概原理,两个差不太多:

配置文件中还是要配一下工厂方法的bean,这个bean里边要引用要创建的bean,然后再设置几个属性,factory-method,指定创建bean对象的方法,后面的步骤就是读取xml,然后通过工厂方法创建bean对象。

<待续>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值