La méthode d'assemblage de Spring Bean et l'utilisation et la différence entre Autowired et Resource

Cet article a participé à l'événement "Newcomer Creation Ceremony" pour commencer ensemble la route de la création d'or.

@ [table des matières]

1. Câblage automatique du ressort

Dans l'utilisation de Spring, si vous souhaitez instancier un bean, vous pouvez utiliser le fichier de configuration ou des annotations dans le code Java pour y parvenir. Spring peut automatiquement coopérer avec la relation entre ces beans en fonction de la relation entre ces beans. Cette fonction automatique processus de coopération, également appelé autowiring. Il existe quatre modes de mode d'assemblage automatique comme suit :

maquette illustrer
non aucun moyen de désactiver l'option de câblage automatique, les dépendances doivent être confirmées via les paramètres affichés. Il s'agit également de l'option par défaut lors de la configuration xml.
de nom L'injection est effectuée en fonction du nom du bean. Lorsque le bean est automatiquement assemblé, le nom de l'attribut est recherché pour le bean correspondant dans le fichier de configuration. Si un bean portant le même nom est trouvé, il sera injecté. S'il n'est pas trouvé, il sera jeté.
par type L'injection est effectuée en fonction du type du bean. Lorsque les propriétés sont automatiquement assemblées dans le bean, le type de propriété défini est mis en correspondance avec le bean défini dans le fichier de configuration. Si le type est le même, il est injecté dans la propriété Si aucun bean de ce type n'est trouvé, il est lancé.
constructor Câblage automatique des beans via le constructeur, cette opération est cohérente avec ByType, dans le processus de câblage automatique, le type de paramètre du constructeur sera trouvé, puis le câblage automatique sera effectué pour tous les paramètres du constructeur.

Il existe trois manières de mettre en œuvre le processus d'assemblage du haricot printanier :

  • emplacement xml
  • @Autowired
  • @Ressource

Configuration 2.xml pour réaliser l'assemblage

Dans un premier temps, trois classes sont définies, à savoir :

La classe User qui représente la relation utilisateur :

package com.dhb.gts.javacourse.week5.springbean.v1;

import lombok.Data;

@Data
public class User {
	//编号
	private int id;
	//姓名
	private String name;
	//年龄
	private int age;

	public User(int id, String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}
}

复制代码

La classe Role représentant le rôle :

package com.dhb.gts.javacourse.week5.springbean.v1;

import lombok.Data;

@Data
public class Role {
	//角色ID
	private int roleId;
	//角色名称
	private String roleName;
}

复制代码

Et la classe UserRole qui représente l'association de rôle d'utilisateur :

package com.dhb.gts.javacourse.week5.springbean.v1;

import lombok.Data;

@Data
public class UserRole {
	//用户
	private User user;
	//角色
	private Role role;

	public UserRole() {
	}

	public UserRole(User user, Role role) {
		this.user = user;
		this.role = role;
	}
}

复制代码

2.1 xml implémente l'assemblage de base

XML d'emplacement :

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.dhb.gts.javacourse.week5.springbean.v1.User">
        <constructor-arg name="id" value="001"/>
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
    
    <bean id="role" class="com.dhb.gts.javacourse.week5.springbean.v1.Role">
        <property name="roleId" value="1"/>
        <property name="roleName" value="管理员"/>
    </bean>
    
    <bean id="userRole" class="com.dhb.gts.javacourse.week5.springbean.v1.UserRole" >
        <property name="role" ref="role"/>
        <property name="user" ref="user"/>
    </bean>
    
</beans>
复制代码

Classe d'essai :

package com.dhb.gts.javacourse.week5.springbean.v1;

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

public class XmlTest1 {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("app-v1-1.xml");
		UserRole userRole = (UserRole) context.getBean("userRole");
		System.out.println(userRole.toString());
	}

}


复制代码

De cette façon, chaque propriété doit être configurée en xml. Tout d'abord, l'utilisateur et le rôle sont assemblés via la propriété, et les deux propriétés de l'objet UserRole, le rôle et l'utilisateur, sont associées via la propriété. De cette façon, l'une des méthodes d'assemblage les plus élémentaires au printemps peut être réalisée. Peut être testé via la classe XmlTest1 pour confirmer l'exactitude de l'assembly.

UserRole(user=User(id=1, name=张三, age=22), role=Role(roleId=1, roleName=管理员))
复制代码

2.2 xml réalise un assemblage automatique via byName

code de configuration 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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.dhb.gts.javacourse.week5.springbean.v1.User">
        <constructor-arg name="id" value="001"/>
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
    
    <bean id="role" class="com.dhb.gts.javacourse.week5.springbean.v1.Role">
        <property name="roleId" value="1"/>
        <property name="roleName" value="管理员"/>
    </bean>

    <bean id="userRole" class="com.dhb.gts.javacourse.week5.springbean.v1.UserRole" autowire="byName"/>
    
</beans>
复制代码

Code d'essai :

package com.dhb.gts.javacourse.week5.springbean.v1;

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

public class XmlTest2 {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("app-v1-2.xml");
		UserRole userRole = (UserRole) context.getBean("userRole");
		System.out.println(userRole.toString());
	}

}


复制代码

这种装配方式不用在UserRole中指定user和role对应的具体类,只需要增加一个属性:autowire="byName",就能在自动装配的过程中,将根据UserRole的属性的name查找context中name与之对应的bean进行装配。 测试结果如下:

UserRole(user=User(id=1, name=张三, age=22), role=Role(roleId=1, roleName=管理员))
复制代码

2.3 xml通过byType实现自动装配

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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.dhb.gts.javacourse.week5.springbean.v1.User">
        <constructor-arg name="id" value="001"/>
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
    
    <bean id="role" class="com.dhb.gts.javacourse.week5.springbean.v1.Role">
        <property name="roleId" value="1"/>
        <property name="roleName" value="管理员"/>
    </bean>

    <bean id="userRole" class="com.dhb.gts.javacourse.week5.springbean.v1.UserRole" autowire="byType"/>
    
</beans>
复制代码

测试代码:

package com.dhb.gts.javacourse.week5.springbean.v1;

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

public class XmlTest3 {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("app-v1-3.xml");
		UserRole userRole = (UserRole) context.getBean("userRole");
		System.out.println(userRole.toString());
	}

}


复制代码

这种装配方式同样不用在UserRole中指定user和role对应的具体类,只需要增加一个属性:autowire="byType",就能在自动装配的过程中,将根据UserRole成员变量的类型查找context中类型与之对应的bean进行装配。 需要注意的是,byName方式可以确保bean的唯一性,但是byType方式,无法确保bean的唯一性,如果出现多个bean的类型相同,则会报错。 测试结果如下:

UserRole(user=User(id=1, name=张三, age=22), role=Role(roleId=1, roleName=管理员))
复制代码

2.4 xml通过constructor实现自动装配

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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.dhb.gts.javacourse.week5.springbean.v1.User">
        <constructor-arg name="id" value="001"/>
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
    
    <bean id="role" class="com.dhb.gts.javacourse.week5.springbean.v1.Role">
        <property name="roleId" value="1"/>
        <property name="roleName" value="管理员"/>
    </bean>

    <bean id="userRole" class="com.dhb.gts.javacourse.week5.springbean.v1.UserRole" autowire="constructor">
        <constructor-arg name="user" ref="user"/>
        <constructor-arg name="role" ref="role"/>
    </bean>
</beans>
复制代码

测试代码:

package com.dhb.gts.javacourse.week5.springbean.v1;

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

public class XmlTest4 {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("app-v1-4.xml");
		UserRole userRole = (UserRole) context.getBean("userRole");
		System.out.println(userRole.toString());
	}

}


复制代码

这种装配方式同样不用在UserRole中指定user和role对应的具体类,只需要增加一个属性:autowire="constructor",就能在自动装配的过程中,将根据UserRole构造函数参数表constructor-arg配置的name查找context中name与之对应的bean进行装配。 测试结果如下:

UserRole(user=User(id=1, name=张三, age=22), role=Role(roleId=1, roleName=管理员))
复制代码

2.@Autowired实现装配

@Autowired是采用byType实现的自动装配,在装配的过程中,通过类型进行匹配。 同样,定义了Role

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Data
public class Role {
	//角色ID
	@Value("2")
	private Integer roleId;
	//角色名称
	@Value("用户")
	private String roleName;
}

复制代码

以及User

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Data
public class User {
	//编号
	private Integer id;
	//姓名
	private String name;
	//年龄
	private Integer age;

	@Autowired
	public User(@Value("1") int id, @Value("用户") String name,@Value("22")  int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}
}

复制代码

2.1 注解在属性上

UserRole代码如下:

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Data
public class UserRole {
	//用户
	@Autowired
	private User user;
	//角色
	@Autowired
	private Role role;

	public UserRole() {
	}

	public UserRole(User user, Role role) {
		this.user = user;
		this.role = role;
	}
}   

复制代码

如上所示,只需要在UserRole的属性上增加@Autpwired,在context中查找与属性类型一致的bean,就可以实现UserRole的自动装配。

2.2 注解在构造函数上

UserRole代码如下:

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Data
public class UserRole1 {
	//用户
	private User user;
	//角色
	private Role role;

	public UserRole1() {
	}

	@Autowired
	public UserRole1(User user, Role role) {
		this.user = user;
		this.role = role;
	}
}

复制代码

注解在构造函数上,等价于xml配置中的constructor配置。通过构造函数的属性值的类型去查找context中的bean。

2.3 注解在Set方法上

UserRole代码如下:

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@ToString
public class UserRole2 {
   //用户
   private User user;
   //角色
   private Role role;


   public User getUser() {
   	return user;
   }

   @Autowired
   public void setUser(User user) {
   	this.user = user;
   }

   public Role getRole() {
   	return role;
   }

   @Autowired
   public void setRole(Role role) {
   	this.role = role;
   }

   public UserRole2() {
   }
   
   public UserRole2(User user, Role role) {
   	this.user = user;
   	this.role = role;
   }
}

复制代码

AutoWired也可以注解在set方法上来实现自动装配。根据set方法的参数,从context中选择type与之一致的bean实现装配。

2.4 测试

测试代码如下:

public class AutowiredTest {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("app-v2.xml");
		UserRole userRole = (UserRole) context.getBean("userRole");
		System.out.println(userRole.toString());
		UserRole1 userRole1 = (UserRole1) context.getBean("userRole1");
		System.out.println(userRole1.toString());
		UserRole2 userRole2 = (UserRole2) context.getBean("userRole2");
		System.out.println(userRole2.toString());
	}
}
复制代码

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: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 http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.dhb.gts.javacourse.week5.springbean.v2">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
</beans>
复制代码

测试结果:

UserRole(user=User(id=1, name=用户, age=22), role=Role(roleId=2, roleName=用户))
UserRole1(user=User(id=1, name=用户, age=22), role=Role(roleId=2, roleName=用户))
UserRole2(user=User(id=1, name=用户, age=22), role=Role(roleId=2, roleName=用户))
复制代码

3.@Resource实现装配

同样,通过J2EE的@Resource标签也能实现Bean的装配,但是需要注意的是,这个注解不支持构造函数,只支持属性或者set方法。需要注意的是,@Resource默认是采用byName的方式从contect中查找bean. 角色类:

package com.dhb.gts.javacourse.week5.springbean.v3;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Data
public class Role {
	//角色ID
	@Value("2")
	private Integer roleId;
	//角色名称
	@Value("用户")
	private String roleName;
}

复制代码

用户类:

package com.dhb.gts.javacourse.week5.springbean.v3;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Data
public class User {
	//编号
	private Integer id;
	//姓名
	private String name;
	//年龄
	private Integer age;

	@Autowired
	public User(@Value("1") int id, @Value("用户") String name,@Value("22")  int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}
}

复制代码

3.1 注解在属性上

代码如下:

package com.dhb.gts.javacourse.week5.springbean.v3;

import lombok.Data;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Data
public class UserRole {
	//用户
	@Resource(type = User.class)
	private User user;
	//角色
	@Resource(name = "role")
	private Role role;

	public UserRole() {
	}

	public UserRole(User user, Role role) {
		this.user = user;
		this.role = role;
	}
}

复制代码

3.2 注解在set方法上

代码如下:

package com.dhb.gts.javacourse.week5.springbean.v3;

import lombok.ToString;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@ToString
public class UserRole1 {
	//用户
	private User user;
	//角色
	private Role role;

	public UserRole1() {
	}

	public User getUser() {
		return user;
	}

	@Resource
	public void setUser(User user) {
		this.user = user;
	}

	public Role getRole() {
		return role;
	}

	@Resource
	public void setRole(Role role) {
		this.role = role;
	}
	
	public UserRole1(User user, Role role) {
		this.user = user;
		this.role = role;
	}
}

复制代码

3.3 @Resource测试:

测试类:

public class ResourceTest {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("app-v3.xml");
		UserRole userRole = (UserRole) context.getBean("userRole");
		System.out.println(userRole.toString());
		UserRole1 userRole1 = (UserRole1) context.getBean("userRole1");
		System.out.println(userRole1.toString());
	}
}

复制代码

测试配置:

<?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 http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.dhb.gts.javacourse.week5.springbean.v3">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
</beans>

复制代码

测试结果:

UserRole(user=User(id=1, name=用户, age=22), role=Role(roleId=2, roleName=用户))
UserRole1(user=User(id=1, name=用户, age=22), role=Role(roleId=2, roleName=用户))
复制代码

4.@Autowired与@Resource的比较

二者对比如下:

  • @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或者在setter方法上。 但是@Resource不支持在构造函数上装配。
  • @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) 。如果我们想使用名称装配可以结合@Qualifier注解进行使用。
  • @Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定, 如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。

Guess you like

Origin juejin.im/post/7084996952554733581