定制网站Spring | Bean自动装配详解

个人主页

前言:定制网站上节我给大家讲解了,定制网站这一节我们讲解Spring中Bean定制网站如何自动装配,定制网站废话不多说,定制网站直接上正文!

文章目录

Bean定制网站的自动装配

5.1、定制网站自动装配说明

  • 定制网站自动装配是使用spring满足bean定制网站依赖的一种方法

  • spring定制网站会在应用上下文中为某个bean定制网站寻找其依赖的bean。

  • Spring中bean定制网站有三种装配机制,分别是:

  1. 在xml定制网站定制网站中显式配置;
  2. 在java中显式配置;
  3. 隐式的bean定制网站发现机制和自动装配。【重要】
  • Spring定制网站的自动装配需要从两个角度来实现,或者说是两个操作:
  1. 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;
  2. 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI;

组件扫描和自动装配组合发挥巨大威力,使得显示的配置降低到最少。

推荐不使用自动装配xml配置 , 而使用注解 .

5.2、测试环境搭建

1、新建一个项目

2、新建两个实体类,Cat Dog 都有一个叫的方法

public class Cat {   public void shout() {       System.out.println("miao~");  }}public class Dog {   public void shout() {       System.out.println("wang~");  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3、新建一个用户类 User

public class User {   private Cat cat;   private Dog dog;   private String name;}
  • 1
  • 2
  • 3
  • 4
  • 5

4、编写Spring配置文件

<?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"       xmlns:c="http://www.springframework.org/schema/c"       xsi:schemaLocation="http://www.springframework.org/schema/beans        https://www.springframework.org/schema/beans/spring-beans.xsd">    <bean id="cat" class="com.bby.pojo.Cat"/>    <bean id="dog" class="com.bby.pojo.Dog"/>    <bean id="user" class="com.bby.pojo.User">        <property name="name" value="啵啵鱼"/>        <property name="cat" ref="cat"/>        <property name="dog" ref="dog"/>    </bean></beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5、测试

public class UserTest {    @Test    public void test() {        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");        User user = context.getBean("user", User.class);        System.out.println(user);        user.getCat().shout();        user.getDog().shout();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

5.3、 自动装配(autowire)

5.3.1、byName (按名称自动装配)

由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。

采用自动装配将避免这些错误,并且使配置简单化。

测试:

1、修改bean配置,增加一个属性 autowire=“byName”

<bean id="user" class="com.bby.pojo.User" autowire="byName">   <property name="name" value="啵啵鱼"/></bean>
  • 1
  • 2
  • 3

2、再次测试,结果依旧成功输出!

3、我们将 cat 的bean id修改为 catXXX

4、再次测试, 执行时报空指针java.lang.NullPointerException。因为按byName规则找不对应set方法,真正的setCat就没执行,对象就没有初始化,所以调用时就会报空指针错误。

小结:

当一个bean节点带有 autowire byName的属性时。

  1. 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。

  2. 去spring容器中寻找是否有此字符串名称id的对象。

  3. 如果有,就取出注入;如果没有,就报空指针异常。

5.3.2、byType (按类型自动装配)

使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常。

NoUniqueBeanDefinitionException
  • 1

测试:

1、将user的bean配置修改一下 : autowire=“byType”

2、测试,正常输出

3、在注册一个cat 的bean对象!

<bean id="dog" class="com.bby.pojo.Dog"/><bean id="cat" class="com.bby.pojo.Cat"/><bean id="cat2" class="com.bby.pojo.Cat"/><bean id="user" class="com.bby.pojo.User" autowire="byType">   <property name="str" value="啵啵鱼"/></bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4、测试,报错:NoUniqueBeanDefinitionException

5、删掉cat2,将cat的bean名称改掉!测试!因为是按类型装配,所以并不会报异常,也不影响最后的结果。甚至将id属性去掉,也不影响结果。

5.3.3、使用注解

jdk1.5开始支持注解,spring2.5开始全面支持注解。

(1)准备工作

1、在spring配置文件中引入context文件头

xmlns:context="http://www.springframework.org/schema/context"	http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
  • 1
  • 2
  • 3
  • 4

2、开启属性注解支持!

<context:annotation-config/>
  • 1

(2)@Autowired

直接在属性上使用即可!也可以再set方式上使用!

使用AutoWired我们可以不用编写Set方法了,前提是这个自动装配的属性在IOC(Spring) 容器中存在

  • @Autowired默认使用 byType来装配属性,如果匹配到类型的多个实例,再通过 byName来确定 bean
  • 需要导入 spring-aop的包!

测试:

1、将User类中的set方法去掉,使用@Autowired注解

public class User {    private String name;    @Autowired    private Cat cat;    @Autowired    private Dog dog;    public String getName() {        return name;    }    public Cat getCat() {        return cat;    }    public Dog getDog() {        return dog;    }    @Override    public String toString() {        return "User{" +                "name='" + name + '\'' +                ", cat=" + cat +                ", dog=" + dog +                '}';    }}
  • 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

科普:

@Nullable //字段标记了这个注解,说明这个字段可以为null
  • 1
//如果允许对象为null,设置required = false,默认为true@Autowired(required = false)private Cat cat;
  • 1
  • 2
  • 3

(3)@Qualifier

  • 加上@Qualifier可以根据byName的方式自动装配
  • @Qualifier不能单独使用。

测试实验步骤:

1、配置文件修改内容,保证类型存在对象。且名字不为类的默认名字(默认名字为类的小写 如:Dog类名字为dog)!

<bean id="dog1" class="com.bby.pojo.Dog"/><bean id="dog2" class="com.bby.pojo.Dog"/><bean id="cat1" class="com.bby.pojo.Cat"/><bean id="cat2" class="com.bby.pojo.Cat"/>
  • 1
  • 2
  • 3
  • 4

2、没有加Qualifier测试,直接报错

3、在属性上添加Qualifier注解

@Autowired@Qualifier(value = "cat2")private Cat cat;@Autowired@Qualifier(value = "dog2")private Dog dog;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

测试,成功输出!

(4)@Resource

  • @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
  • 其次再进行默认的byName方式进行装配;
  • 如果以上都不成功,则按byType的方式自动装配。
  • 都不成功,则报异常。

实体类:

public class User {   //如果允许对象为null,设置required = false,默认为true   @Resource(name = "cat2")   private Cat cat;   @Resource   private Dog dog;   private String str;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

beans.xml

<bean id="dog" class="com.bby.pojo.Dog"/><bean id="cat1" class="com.bby.pojo.Cat"/><bean id="cat2" class="com.bby.pojo.Cat"/><bean id="user" class="com.bby.pojo.User"/>
  • 1
  • 2
  • 3
  • 4
  • 5

测试:结果OK

配置文件2:beans.xml , 删掉cat2

<bean id="dog" class="com.bby.pojo.Dog"/><bean id="cat1" class="com.bby.pojo.Cat"/>
  • 1
  • 2

实体类上只保留注解

@Resourceprivate Cat cat;@Resourceprivate Dog dog;
  • 1
  • 2
  • 3
  • 4

结果:OK

结论:先进行byName查找,失败;再进行byType查找,成功。

(5)@Resource 和 @Autowired的区别

  • 都是用来自动装配的,都可以放在属性字段上
  • @Autowired默认通过byType 的方式,当匹配到多个同类型时,使用byName进行装配,默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
  • @Resource(属于J2EE复返)默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果name属性一旦指定,就只会按照名称进行装配。如果两个都找不到就报错
  • 它们的作用相同都是用注解方式注入对象,但执行顺序不同,@Autowired先byType,@Resource先byName。

尾言:创作不易,如果本文的内容对您有帮助,还望客官可以三连支持一下博主,👍(点赞)+✏️(评论)+⭐️(收藏)是我创作的巨大动力!

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发