三种方法实现依赖注入

1 使用XML文件实现依赖注入

1.1 setter实现依赖注入

通过标签下的标签进行注入。

  1. 若要注入简单值,则通过的value属性
  2. 若要注入引用其他的bean的id或name,则使用的ref属性
  3. 若要注入集合,则下有对应。若注入简单值,直接使用;如果集合中是引用的其他bean,使用
  4. 对于map存储的是键值对,应使用标签。如果键是简单值,则使用key属性指定其值,如果是引用的其他bean,使用key-ref属性指定bean的id或name;如果值是简单值,则使用value属性指定其值,如果是引用的其他bean,使用value-ref属性指定bean的id或name
  5. 注入Properties集合,可以使用

1.1.1 注入简单值(基本数据类型或字符串)


	
    

 1.1.2 注入引用的其他bean(引用类型)


	
	

1.1.3 注入集合(Set、List、Map、Properties) 


	
	
	
		
		
			
			
			
			山东分公司
			山西分公司
			广东分公司
			广西分公司
			海南分公司
		
	
	
		
			
			
			
			Oracle
			Microsoft
			IBM
			Google
		
	
	
		
			
			
			
		
	
	
		
			
			
			
			
			
		
	
	
	
		
			1000000
			小胖
			Joint venture
		
	
	
		
			registeredCapital=2000000
			legalPerson=Allen
			type=Joint venture
		
	

注意:在相应类中,必须要给对应的属性生成setter访问器,因为要使用setXXX()方法来注入/设置需要的值 

诸如在Girl类中:

public class Girl implements Person {

	private String name;
	private Axe axe;
	private Pet pet;
	
	public Girl() {
	}

	public Girl(String name, Axe axe, Pet pet) {
		this.name = name;
		this.axe = axe;
		this.pet = pet;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setAxe(Axe axe) {
		this.axe = axe;
	}

	public void setPet(Pet pet) {
		this.pet = pet;
	}

	@Override
	public void kanChai() {

		System.out.println("Girl砍柴,力气更大!!!");
		axe.cut();
		pet.showSkill();
	}
}

1.2 构造函数实现依赖注入

通过标签下的标签实现注入。注意,如果使用setter注入,的name属性是类中的属性名;但这里使用构造函数注入,的name属性指定的是构造函数的参数的名称。也可不写参数名称,但是必须保证参数的顺序是对的。可以使用参数索引index属性(0表示第一个参数),这样参数顺序随便写。但是如果不写参数名称,也不写参数索引,则参数顺序必须正确。

  1. 注入简单值,通过value属性指定要注入的值即可
  2.  如果注入引用的其他bean,使用ref属性指定要注入的bean的id或name
  3. 若要注入集合,则下有对应。若注入简单值,直接使用;如果集合中是引用的其他bean,使用
  4. 对于map存储的是键值对,应使用标签。如果键是简单值,则使用key属性指定其值,如果是引用的其他bean,使用key-ref属性指定bean的id或name;如果值是简单值,则使用value属性指定其值,如果是引用的其他bean,使用value-ref属性指定bean的id或name
  5. 注入Properties集合,可以使用

1.2.1 注入简单值(基本数据类型或字符串)


	
	

使用构造函数注入,也可不写参数名称,但是必须保证参数的顺序是对的。

可以使用参数索引(0表示第一个参数),这样参数顺序随便写。

但是如果不写参数名称,也不写参数索引,则参数顺序必须正确。


	
	
	

 1.2.2 注入引用的其他bean(引用类型)


	
	
	
	
	

1.2.3 注入集合(Set、List、Map、Properties) 


	
	
	
		
			
			山东分公司
			山西分公司
			广东分公司
			广西分公司
			海南分公司
		
	
	
		
			Oracle
			Microsoft
			IBM
			Google
		
	
	
		
			
			
			
		
	
	
		
			
			
			
			
			
		
	
	
	
		
			1000000
			小胖
			Joint venture
		
	
	
		
			registeredCapital=2000000
			legalPerson=Allen
			type=Joint venture
		
	

 注意:在相应类中,必须要生成构造函数:

public class Address {

    private String province; //省
    private String city; 	 //市
    private String detailedAddress; //详细地址
    
	@Override
	public String toString() {
		return "地址::" + province + "省" + city + "市" + detailedAddress;
	}

	public Address() {
		super();
	}

	public Address(String pro, String city, String detailedAddress) {
		System.out.println("调用了带3个参数的构造函数实现依赖注入!!!");
		this.province = pro;
		this.city = city;
		this.detailedAddress = detailedAddress;
	}

	public void setProvince(String province) {
		System.out.println("setProvince()方法被调用........");
		this.province = province;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public void setDetailedAddress(String detailedAddress) {
		this.detailedAddress = detailedAddress;
	}
}

1.3 自动装配

在应用程序对象之间创建和管理关联的过程叫做装配,这构成了DI的核心。以上两种方法为显示装配(显式声明Bean之间的依赖),自动装配(autowiring)不显式声明Bean之间的依赖,让容器选择合适的依赖项注入。

1.3.1 byName

 byName是按照名称自动装配,意思是要注入的属性的属性名和要注入的bean的id或name(别名)相同,即可实现按照名称自动装配。

当一个bean带有autowire byName的属性时:

  1. 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
  2. 去spring容器中寻找是否有此字符串名称id的对象。
  3. 如果有,就取出注入;如果没有,就报空指针异常


    

1.3.2 byType

byType是按照类型自动装配。如果要注入的属性的数据类型和容器中某个bean的类型匹配,则实现自动装配。

自动装配跟 id 无关,在配置bean 时不写 id 都不会报错。

但是 byType 的自动装配存在一个很严重的问题,因为不是通过唯一的 id 来匹配,而是通过类型来匹配,所以容器中不能存在多个相同类型的 bean,否则会抛出NoUniqueBeanDefinitionException异常。



	
	

1.3.3 constructor

constructor表示使用对应的构造函数实现自动装配,所以需要生成对应的构造函数



	

public class Girl implements Person {
 
	private String name;
	private Axe axe;
	private Pet pet;
	
	@Override
	public void kanChai() {
		System.out.println("砍柴人:"+name);
		System.out.println("Girl砍柴,力气更大!!!");
		pet.showSkill();
		axe.cut();
	}
 
	public Girl() {
		super();
	}
 
	//如果使用构造函数实现自动装配,需要生成对应的构造函数
	//使用constructor实现自动装配,只要构造函数的数据类型对了即可,参数名无所谓
	public Girl(Axe a, Pet p) {
		super();
		System.out.println("带2个参数的构造函数~~~");
		this.axe = a;
		this.pet = p;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public void setAxe(Axe axe) {
		this.axe = axe;
	}
 
	public void setPet(Pet pet) {
		this.pet = pet;
	}
}

2 使用Java代码实现依赖注入

2.1 调用@Bean修饰的对应方法实现注入

使用Java代码进行注入,首先要先写一个Java代码的Spring配置类SpringConfig1.class

首先要注意,配置类需要用@Configuration注解修饰。而且由于我们使用的是java配置类,而不是xml配置文件,则需要使用ApplicationContext接口的AnnotationConfigApplicationContext实现类来创建容器。

ApplicationContext ctx 
	= new AnnotationConfigApplicationContext(SpringConfig.class);

使用@Bean修饰的方法注册一个bean成为spring管理的bean,方法返回的对象成为Spring管理的bean。于是, 可通过调用产生bean的方法来获取一个bean实现依赖注入。

@Configuration
public class SpringConfig1 {
	
	@Bean
	public Axe fuzi() {
		return new SteelAxe();
	}
	
	@Bean
	public Pet chongwu() {
		return new Pig();
	}
	

	@Bean
	public Person person() {
		Girl girl=new Girl();
		girl.setName("小花");
		girl.setAxe(fuzi()); //调用fuzi()方法获取的是spring管理的SteelAxe对象
		girl.setPet(chongwu()); //调用chongwu()方法获取的是spring管理的Pig对象
		return girl;
	}
}

2.2 通过方法参数获取要注入的bean 

同上,首先要有一个Spring的配置类SpringConfig2.class。仍然使用@Bean修饰的方法注册一个bean成为spring管理的bean。

这一方法与2.1不同的是,这一种直接在方法上添加对应类型的参数,使用传入的参数设置属性实现依赖注入。参数的名称和顺序无所谓,只要参数类型对了即可。

@Bean
public Person person(Pet p,Axe a) {
	Girl girl=new Girl();
	girl.setName("小花");
	girl.setAxe(a); //直接使用传入的参数进行注入即可
	girl.setPet(p); 
	return girl;
}

 3 使用注解实现依赖注入

使用注解,首先要在Spring的配置类中使用@ComponentScan开启包扫描,也别忘记@Configuration。使用注解的一个好处就是SpringConfig.class非常简单:

@Configuration
@ComponentScan("com.qdu.bean")
//@ComponentScan({"com.qdu.bean","com.qdu.service","com.qdu.dao"})
public class SpringConfig {
	
}

开启包扫描后,别忘记在每个类使用添加注解@Component,将一个类注册为spring管理的bean

在字段前使用@Autowired注解,则使用反射实现注入。@Autowired注解按照类型进行装配,如果存在多个匹配类型,会报错。@Autowired可用于构造函数前、setter方法前、其他任何用于注入的方法前或字段前。

@Component
public class Girl implements Person {

	private String name;
	
	@Autowired
	private Axe axe;
	
	@Autowired
	private Pet pet;

	public Girl() {
	}

	public Girl(String name, Axe axe, Pet pet) {
		this.name = name;
		this.axe = axe;
		this.pet = pet;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setAxe(Axe axe) {
		this.axe = axe;
	}

	public void setPet(Pet pet) {
		this.pet = pet;
	}

	@Override
	public void kanChai() {
		System.out.println("Girl砍柴,力气更大!!!");
		axe.cut();
		pet.showSkill();
	}
}

你可能感兴趣的:(spring,依赖注入,后端)